You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
3.0 KiB
102 lines
3.0 KiB
#include "addition.h"
|
|
#include <stdlib.h>
|
|
|
|
// Struct for number in floating and integer
|
|
|
|
struct data
|
|
{
|
|
union {
|
|
float floating;
|
|
unsigned int integer;
|
|
} number;
|
|
unsigned int sign;
|
|
unsigned int exponent;
|
|
unsigned int precision;
|
|
};
|
|
|
|
// full_adder is an implementation of two bit addition with carry
|
|
|
|
void full_adder (num* sum, num* nextcarry, num number1, num number2, num carry) {
|
|
sum[0] = (number1 % 2) ^ (number2 % 2) ^ (carry % 2);
|
|
|
|
nextcarry[0] = ((number1 % 2) & (number2 % 2)) | ((number1 % 2) & (carry % 2)) | ((number2 % 2) & (carry % 2));
|
|
}
|
|
|
|
// addition is an implementation of an 32 bit addition
|
|
|
|
unsigned int addition_uint(num number1, num number2) {
|
|
unsigned int result = 0;
|
|
num sum[1] = {0};
|
|
num nextcarry[1] = {0};
|
|
|
|
for (int i = 0; i < 8 * sizeof(num); i++)
|
|
{
|
|
full_adder(sum, nextcarry, number1, number2, nextcarry[0]);
|
|
result ^= (sum[0] << i);
|
|
|
|
number1 >>= 1;
|
|
number2 >>= 1;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// reading sign out of an integer (floating number)
|
|
|
|
unsigned int sign_float(unsigned int number) {
|
|
return number >> 31;
|
|
}
|
|
|
|
// reading precision out of an integer (floating number)
|
|
|
|
unsigned int precision_float(unsigned int number) {
|
|
unsigned int precision = 8388607;
|
|
return (number & precision);
|
|
}
|
|
|
|
// reading exponent out of an integer (floating number)
|
|
|
|
unsigned int exponent_float(unsigned int number) {
|
|
unsigned int exponent = 2139095040;
|
|
return (number & exponent) >> 23;
|
|
}
|
|
|
|
// adding two precision together
|
|
|
|
unsigned int addition_precision_float(unsigned int p1, unsigned int p2) {
|
|
return addition_uint(p1, p2);
|
|
}
|
|
|
|
// writing number out of sign, exponent and precision
|
|
|
|
unsigned int output_float(unsigned int sign, unsigned int exponent, unsigned int precision) {
|
|
return (sign << 31) | (exponent << 23) | precision;
|
|
}
|
|
|
|
// addition of two floating numbers
|
|
|
|
float addition_float(float number1, float number2) {
|
|
if (number2 == (float) 0.0) return number1;
|
|
else if (number1 == (float) 0.0) return number2;
|
|
else if (number2 > number1) return addition_float(number2, number1);
|
|
|
|
unsigned int e = 8388608;
|
|
struct data num1, num2, num3;
|
|
num1.number.floating = number1, num2.number.floating = number2;
|
|
num1.sign = sign_float(num1.number.integer), num2.sign = sign_float(num2.number.integer);
|
|
num1.exponent = exponent_float(num1.number.integer), num2.exponent = exponent_float(num2.number.integer);
|
|
num1.precision = precision_float(num1.number.integer) | e, num2.precision = precision_float(num2.number.integer) | e;
|
|
|
|
num3.precision = addition_precision_float(num1.precision, num2.precision >> (num1.exponent - num2.exponent));
|
|
if (num3.precision > 16777215) {
|
|
num3.exponent = addition_uint(num1.exponent, 1);
|
|
num3.precision = (num3.precision >> 1);
|
|
}
|
|
else {
|
|
num3.exponent = num1.exponent;
|
|
}
|
|
num3.precision ^= e;
|
|
num3.number.integer = output_float(num1.sign, num3.exponent, num3.precision);
|
|
|
|
return num3.number.floating;
|
|
}
|