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.

101 lines
3.0 KiB

  1. #include "addition.h"
  2. #include <stdlib.h>
  3. // Struct for number in floating and integer
  4. struct data
  5. {
  6. union {
  7. float floating;
  8. unsigned int integer;
  9. } number;
  10. unsigned int sign;
  11. unsigned int exponent;
  12. unsigned int precision;
  13. };
  14. // full_adder is an implementation of two bit addition with carry
  15. void full_adder (num* sum, num* nextcarry, num number1, num number2, num carry) {
  16. sum[0] = (number1 % 2) ^ (number2 % 2) ^ (carry % 2);
  17. nextcarry[0] = ((number1 % 2) & (number2 % 2)) | ((number1 % 2) & (carry % 2)) | ((number2 % 2) & (carry % 2));
  18. }
  19. // addition is an implementation of an 32 bit addition
  20. unsigned int addition_uint(num number1, num number2) {
  21. unsigned int result = 0;
  22. num sum[1] = {0};
  23. num nextcarry[1] = {0};
  24. for (int i = 0; i < 8 * sizeof(num); i++)
  25. {
  26. full_adder(sum, nextcarry, number1, number2, nextcarry[0]);
  27. result ^= (sum[0] << i);
  28. number1 >>= 1;
  29. number2 >>= 1;
  30. }
  31. return result;
  32. }
  33. // reading sign out of an integer (floating number)
  34. unsigned int sign_float(unsigned int number) {
  35. return number >> 31;
  36. }
  37. // reading precision out of an integer (floating number)
  38. unsigned int precision_float(unsigned int number) {
  39. unsigned int precision = 8388607;
  40. return (number & precision);
  41. }
  42. // reading exponent out of an integer (floating number)
  43. unsigned int exponent_float(unsigned int number) {
  44. unsigned int exponent = 2139095040;
  45. return (number & exponent) >> 23;
  46. }
  47. // adding two precision together
  48. unsigned int addition_precision_float(unsigned int p1, unsigned int p2) {
  49. return addition_uint(p1, p2);
  50. }
  51. // writing number out of sign, exponent and precision
  52. unsigned int output_float(unsigned int sign, unsigned int exponent, unsigned int precision) {
  53. return (sign << 31) | (exponent << 23) | precision;
  54. }
  55. // addition of two floating numbers
  56. float addition_float(float number1, float number2) {
  57. if (number2 == (float) 0.0) return number1;
  58. else if (number1 == (float) 0.0) return number2;
  59. else if (number2 > number1) return addition_float(number2, number1);
  60. unsigned int e = 8388608;
  61. struct data num1, num2, num3;
  62. num1.number.floating = number1, num2.number.floating = number2;
  63. num1.sign = sign_float(num1.number.integer), num2.sign = sign_float(num2.number.integer);
  64. num1.exponent = exponent_float(num1.number.integer), num2.exponent = exponent_float(num2.number.integer);
  65. num1.precision = precision_float(num1.number.integer) | e, num2.precision = precision_float(num2.number.integer) | e;
  66. num3.precision = addition_precision_float(num1.precision, num2.precision >> (num1.exponent - num2.exponent));
  67. if (num3.precision > 16777215) {
  68. num3.exponent = addition_uint(num1.exponent, 1);
  69. num3.precision = (num3.precision >> 1);
  70. }
  71. else {
  72. num3.exponent = num1.exponent;
  73. }
  74. num3.precision ^= e;
  75. num3.number.integer = output_float(num1.sign, num3.exponent, num3.precision);
  76. return num3.number.floating;
  77. }