Advertisement
Guest User

Untitled

a guest
Feb 17th, 2020
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.24 KB | None | 0 0
  1. uint32_t add(uint32_t x, uint32_t y) {
  2. uint32_t result_mantissa;
  3. uint32_t result_exponent;
  4. uint32_t result_sign;
  5.  
  6. uint32_t different_sign = sign(x) ^ sign(y); //boolean but lets not do any type casting
  7.  
  8. // catch NaN
  9. if (!(exponent(x) ^ 0xFF) && mantissa(x)) return x;
  10. if (!(exponent(y) ^ 0xFF) && mantissa(y)) return y;
  11.  
  12. // catch Inf
  13. if (!(exponent(x) ^ 0xFF) && !(exponent(y) ^ 0xFF)) {
  14. // both are inf
  15. if (different_sign)
  16. // Inf - Inf
  17. return 0x7F800000 + 1; // NaN
  18. else
  19. // both Inf or -Inf
  20. return x;
  21. }
  22. else if (!(exponent(x) ^ 0xFF)) return x;
  23. else if (!(exponent(y) ^ 0xFF)) return y;
  24.  
  25. // both numbers are non-special
  26. uint32_t exp_difference;
  27. if (different_sign) {
  28. exp_difference = exponent(y) + exponent(x);
  29. }
  30. else {
  31. // no need to account for constant BO
  32. // beware of underflow
  33. if (exponent(x) > exponent(y)) exp_difference = exponent(x) - exponent(y);
  34. else exp_difference = exponent(y) - exponent(x);
  35. }
  36.  
  37.  
  38. bool x_bigger_abs;
  39. if (exponent(x) > exponent(y)) x_bigger_abs = true;
  40. else if (exponent(x) < exponent(y)) x_bigger_abs = false;
  41. else if (mantissa(x) > mantissa(y)) x_bigger_abs = true;
  42. else x_bigger_abs = false;
  43.  
  44. if (!different_sign) {
  45. //both numbers have same sign (this is a sum)
  46. result_sign = sign(x);
  47.  
  48. if (x_bigger_abs) {
  49. result_mantissa = (mantissa(x) << 1) + (mantissa(y) << 1) >> exp_difference;
  50. result_exponent = exponent(x);
  51. }
  52. else {
  53. result_mantissa = (mantissa(y) << 1) + ((mantissa(x) << 1) >> exp_difference);
  54. result_exponent = exponent(y);
  55. }
  56. if (result_mantissa << 31) result_mantissa = (result_mantissa >> 1) + 1;
  57. else result_mantissa = (result_mantissa >> 1);
  58. }
  59. else {
  60. // this actually is a subtraction
  61.  
  62. if (x_bigger_abs) {
  63. result_sign = sign(x);
  64. result_exponent = exponent(x);
  65.  
  66. // subtract and round to 23 bit
  67. // this means making room in our 32bit representation
  68. result_mantissa = (mantissa(x) << 1) - ((mantissa(y) << 1) >> exp_difference );
  69. }
  70. else {
  71. result_sign = sign(y);
  72. result_exponent = exponent(y);
  73.  
  74. // subtract and round to 23 bit
  75. // this means making room in our 32bit representation
  76. result_mantissa = (mantissa(y) << 1) - ((mantissa(x) << 1) >> exp_difference);
  77. }
  78.  
  79. if (result_mantissa << 31) result_mantissa = ((result_mantissa >> 1) + 1);
  80. else result_mantissa = (result_mantissa >> 1);
  81.  
  82. // normalize mantissa
  83. uint32_t temp = result_mantissa << 9;
  84. for (uint32_t count = 0; count < 23; ++count) {
  85. if (!((temp << count) >> 31)) {
  86. result_mantissa <<= ++count; // leading 1, so shift 1 more time
  87. result_exponent -= count;
  88. break;
  89. }
  90. }
  91. }
  92. uint32_t result = result_sign << 31 | result_exponent << 23 | result_mantissa;
  93. return result;
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement