Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.29 KB | None | 0 0
  1. /*
  2. * main.c
  3. *
  4. * Created on: Apr 2, 2019
  5. * Author: amras
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <stdint.h>
  11. #include "diag/Trace.h"
  12.  
  13. #include "stm32f4xx.h"
  14. #include "stm32f4xx_hal.h"
  15.  
  16. #pragma GCC diagnostic push
  17. #pragma GCC diagnostic ignored "-Wunused-parameter"
  18. #pragma GCC diagnostic ignored "-Wmissing-declarations"
  19. #pragma GCC diagnostic ignored "-Wreturn-type"
  20.  
  21. #define MANTISSA_BITS 23
  22. #define EXPONENT_BITS 8
  23.  
  24. #define FIRST_BIT (1 << (MANTISSA_BITS - 1))
  25. #define MAX_MANTISSA ((1 << MANTISSA_BITS) - 1)
  26. #define MANTISSA_MASK MAX_MANTISSA
  27.  
  28. #define MAX_EXPONENT ((1 << EXPONENT_BITS) - 1)
  29. #define EXPONENT_OFFSET (MAX_EXPONENT >> 1)
  30.  
  31. struct floating {
  32. uint8_t sign:1;
  33. uint32_t mantissa:MANTISSA_BITS;
  34. uint8_t exponent:EXPONENT_BITS;
  35. };
  36.  
  37. struct floating zero(){
  38. struct floating f;
  39. f.sign = 1;
  40. f.mantissa = 0;
  41. f.exponent = 0;
  42. return f;
  43. }
  44.  
  45. struct floating infinity() {
  46. struct floating f;
  47. f.sign = 1;
  48. f.mantissa = 0;
  49. f.exponent = MAX_EXPONENT;
  50. return f;
  51. }
  52.  
  53. struct floating two() {
  54. struct floating f;
  55. f.sign = 1;
  56. f.mantissa = 0;
  57. f.exponent = EXPONENT_OFFSET + 1;
  58. return f;
  59. }
  60.  
  61. struct floating negate(struct floating f) {
  62. f.sign = !f.sign;
  63. return f;
  64. }
  65.  
  66. struct floating add(struct floating a, struct floating b) {
  67. struct floating res;
  68. struct floating bigger, smaller;
  69. uint8_t exp, exp_diff;
  70. uint32_t bigger_mantissa, smaller_mantissa, mantissa;
  71.  
  72. if (a.exponent == b.exponent) {
  73. if (a.mantissa >= b.mantissa) {
  74. bigger = a;
  75. smaller = b;
  76. } else {
  77. bigger = b;
  78. smaller = a;
  79. }
  80. }
  81. if (a.exponent > b.exponent) {
  82. bigger = a;
  83. smaller = b;
  84. }
  85. if (a.exponent < b.exponent) {
  86. bigger = b;
  87. smaller = a;
  88. }
  89.  
  90. exp = bigger.exponent;
  91. exp_diff = bigger.exponent - smaller.exponent;
  92. bigger_mantissa = bigger.mantissa;
  93. smaller_mantissa = smaller.mantissa >> exp_diff;
  94. if (exp_diff > 0) {
  95. smaller_mantissa |= FIRST_BIT >> (exp_diff - 1);
  96. }
  97.  
  98. if (bigger.sign == smaller.sign) {
  99. // adding
  100. if (exp_diff == 0 || smaller_mantissa > MAX_MANTISSA - bigger_mantissa) {
  101. // overflow
  102. exp++;
  103. bigger_mantissa = bigger_mantissa >> 1 | FIRST_BIT;
  104. if (exp_diff == 0)
  105. smaller_mantissa = smaller_mantissa >> 1 | FIRST_BIT;
  106. else
  107. smaller_mantissa = smaller_mantissa >> 1;
  108. }
  109. mantissa = bigger_mantissa + smaller_mantissa;
  110. } else {
  111. // subtracting
  112. mantissa = bigger_mantissa - smaller_mantissa;
  113.  
  114. if (exp_diff == 0 || smaller_mantissa > bigger_mantissa) {
  115. while ((mantissa & FIRST_BIT) == 0) {
  116. mantissa = mantissa & MANTISSA_MASK;
  117. if (mantissa == 0)
  118. return zero();
  119. exp--;
  120. mantissa = mantissa << 1;
  121. }
  122. // shift one more bit because of the implied leading '1'
  123. exp--;
  124. mantissa = mantissa << 1;
  125. }
  126. }
  127.  
  128. mantissa = mantissa & MANTISSA_MASK;
  129.  
  130. res.sign = bigger.sign;
  131. res.mantissa = mantissa;
  132. res.exponent = exp;
  133.  
  134. return res;
  135. }
  136.  
  137. struct floating sub(struct floating a, struct floating b) {
  138. return add(a, negate(b));
  139. }
  140.  
  141. struct floating frac(struct floating f) {
  142. if (f.mantissa == 0)
  143. return zero();
  144. while ((f.mantissa & FIRST_BIT) == 0) {
  145. f.mantissa <<= 1;
  146. f.exponent--;
  147. }
  148. f.mantissa <<= 1;
  149. f.exponent--;
  150.  
  151. f.mantissa &= MANTISSA_MASK;
  152.  
  153. return f;
  154. }
  155.  
  156. struct floating multiply(struct floating a, struct floating b){
  157. struct floating pa, pb, fa, fb, out;
  158.  
  159.  
  160. if (a.exponent == 0 || b.exponent == 0)
  161. return zero();
  162.  
  163. if (a.mantissa == 0 && b.mantissa == 0){
  164. out.sign = a.sign == b.sign ? 1 : 0;
  165. out.exponent = a.exponent - EXPONENT_OFFSET + b.exponent;
  166. out.mantissa = 0;
  167. return out;
  168. }
  169.  
  170. pa = a;
  171. pb = b;
  172. pa.mantissa = 0;
  173. pb.mantissa = 0;
  174. fa = frac(a);
  175. fb = frac(b);
  176.  
  177. return add(multiply(pa, pb),
  178. add(multiply(pb, fa),
  179. add(multiply(pa, fb),
  180. multiply(fa, fb))));
  181. }
  182.  
  183. struct floating reciprocal(struct floating f) {
  184. struct floating guess;
  185. uint8_t i;
  186.  
  187. guess.sign = f.sign;
  188. guess.mantissa = 0;
  189. guess.exponent = -(f.exponent - EXPONENT_OFFSET) + EXPONENT_OFFSET;
  190.  
  191. for (i=0; i<32; ++i)
  192. guess = multiply(guess, sub(two(), multiply(f, guess)));
  193.  
  194. return guess;
  195. }
  196.  
  197. struct floating divide(struct floating a, struct floating b){
  198. return multiply(a, reciprocal(b));
  199. }
  200.  
  201. int ipow(int base, int exponent) {
  202. int i, res;
  203. for (i=0, res=1; i<exponent; ++i, res=res*base);
  204. return res;
  205. }
  206.  
  207. void show(char* str, struct floating f, int digits){
  208. int e;
  209. uint32_t whole, decimal;
  210. uint64_t a, b, c, d;
  211.  
  212. e = f.exponent - ((1 << (EXPONENT_BITS - 1)) - 1);
  213. if (e >= 0) {
  214. // exponent is positive
  215. // multiply by 2^exponent
  216. whole = (f.mantissa >> (MANTISSA_BITS - e))
  217. // and add 2^exponent because of the implied '1' in mant.
  218. + (1 << e);
  219. decimal = (f.mantissa << e) & MANTISSA_MASK;
  220. }
  221. else {
  222. whole = 0;
  223. decimal = (f.mantissa >> (0 - e)) + (1 << (MANTISSA_BITS + e));
  224. }
  225.  
  226. a = (unsigned long) ipow(10, digits); // 100000
  227. b = (unsigned long) decimal; // 4194304
  228. c = a * b; // 2818572288 WHY
  229. //d = (unsigned long) decimal * (unsigned long) ipow(10, digits);
  230. d = c / (1 << MANTISSA_BITS);
  231.  
  232. decimal = d;
  233. str[0] = f.sign > 0 ? '+' : '-';
  234. sprintf(str+1, "%d.%d", (int)whole, (int)decimal);
  235. }
  236.  
  237. int main(int argc, char* argv[])
  238. {
  239. struct floating f, g, h;
  240. char buffer[128];
  241.  
  242. trace_puts("Running");
  243.  
  244. // f = 3.0f;
  245. f.sign = 1;
  246. f.mantissa = FIRST_BIT;
  247. f.exponent = 128;
  248.  
  249. // g = 5.0f;
  250. g.sign = 0;
  251. g.mantissa = (FIRST_BIT >> 1) + (FIRST_BIT >> 2);
  252. g.exponent = 129;
  253.  
  254. // h = some random value
  255. h.sign = 1;
  256. h.mantissa = FIRST_BIT + (FIRST_BIT >> 3) + (FIRST_BIT >> 5) + (FIRST_BIT >> 14) + (FIRST_BIT >> 20);
  257. h.exponent = 139;
  258.  
  259. show(buffer, f, 5);
  260. trace_puts("F = ");
  261. trace_puts(buffer);
  262.  
  263. show(buffer, g, 5);
  264. trace_puts("G = ");
  265. trace_puts(buffer);
  266.  
  267. show(buffer, h, 5);
  268. trace_puts("H = ");
  269. trace_puts(buffer);
  270.  
  271. show(buffer, add(f, g), 5);
  272. trace_puts("F+G = ");
  273. trace_puts(buffer);
  274.  
  275. show(buffer, sub(f, g), 5);
  276. trace_puts("F-G = ");
  277. trace_puts(buffer);
  278.  
  279. show(buffer, sub(h, h), 5);
  280. trace_puts("H-H = ");
  281. trace_puts(buffer);
  282.  
  283. show(buffer, add(h, g), 5);
  284. trace_puts("H+G = ");
  285. trace_puts(buffer);
  286.  
  287. show(buffer, multiply(f, g), 5);
  288. trace_puts("F*G = ");
  289. trace_puts(buffer);
  290.  
  291. show(buffer, multiply(g, g), 5);
  292. trace_puts("G*G = ");
  293. trace_puts(buffer);
  294.  
  295. show(buffer, multiply(f, h), 5);
  296. trace_puts("F*H = ");
  297. trace_puts(buffer);
  298.  
  299. show(buffer, divide(g, g), 5);
  300. trace_puts("G/G = ");
  301. trace_puts(buffer);
  302.  
  303.  
  304. show(buffer, divide(h, f), 5);
  305. trace_puts("H/F = ");
  306. trace_puts(buffer);
  307.  
  308. show(buffer, divide(g, f), 5);
  309. trace_puts("G/F = ");
  310. trace_puts(buffer);
  311.  
  312. return 0;
  313. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement