fork(1) download
  1. #include <stdio.h>
  2. #include <limits.h>
  3.  
  4. #if UINT_MAX >= 0xFFFFFFFF
  5. typedef unsigned myfloat;
  6. #else
  7. typedef unsigned long myfloat;
  8. #endif
  9.  
  10. #define MF_EXP_BIAS 0x80
  11.  
  12. myfloat mfadd(myfloat a, myfloat b)
  13. {
  14. unsigned ea = a >> 16, eb = b >> 16;
  15. if (ea > eb)
  16. {
  17. a &= 0xFFFF;
  18. b = (b & 0xFFFF) >> (ea - eb);
  19. if ((a += b) > 0xFFFF)
  20. a >>= 1, ++ea;
  21. return a | ((myfloat)ea << 16);
  22. }
  23. else if (eb > ea)
  24. {
  25. b &= 0xFFFF;
  26. a = (a & 0xFFFF) >> (eb - ea);
  27. if ((b += a) > 0xFFFF)
  28. b >>= 1, ++eb;
  29. return b | ((myfloat)eb << 16);
  30. }
  31. else
  32. {
  33. return (((a & 0xFFFF) + (b & 0xFFFF)) >> 1) | ((myfloat)++ea << 16);
  34. }
  35. }
  36.  
  37. myfloat mfmul(myfloat a, myfloat b)
  38. {
  39. unsigned ea = a >> 16, eb = b >> 16, e = ea + eb - MF_EXP_BIAS;
  40. myfloat p = ((a & 0xFFFF) * (b & 0xFFFF)) >> 16;
  41. return p | ((myfloat)e << 16);
  42. }
  43.  
  44. myfloat double2mf(double x)
  45. {
  46. myfloat f;
  47. unsigned e = MF_EXP_BIAS + 16;
  48. if (x <= 0)
  49. return 0;
  50. while (x < 0x8000)
  51. x *= 2, --e;
  52. while (x >= 0x10000)
  53. x /= 2, ++e;
  54. f = x;
  55. return f | ((myfloat)e << 16);
  56. }
  57.  
  58. double mf2double(myfloat f)
  59. {
  60. double x;
  61. unsigned e = (f >> 16) - 16;
  62. if ((f & 0xFFFF) == 0)
  63. return 0;
  64. x = f & 0xFFFF;
  65. while (e > MF_EXP_BIAS)
  66. x *= 2, --e;
  67. while (e < MF_EXP_BIAS)
  68. x /= 2, ++e;
  69. return x;
  70. }
  71.  
  72. int main(void)
  73. {
  74. double testConvData[] = { 1e-18, .25, 0.3333333, .5, 1, 2, 3.141593, 1e18 };
  75. unsigned i;
  76. for (i = 0; i < sizeof(testConvData) / sizeof(testConvData[0]); i++)
  77. printf("%e -> 0x%06lX -> %e\n",
  78. testConvData[i],
  79. (unsigned long)double2mf(testConvData[i]),
  80. mf2double(double2mf(testConvData[i])));
  81.  
  82. printf("300 * 5 = %e\n", mf2double(mfmul(double2mf(300),double2mf(5))));
  83. printf("500 + 3 = %e\n", mf2double(mfadd(double2mf(500),double2mf(3))));
  84. printf("1e18 * 1e-18 = %e\n", mf2double(mfmul(double2mf(1e18),double2mf(1e-18))));
  85. printf("1e-18 + 2e-18 = %e\n", mf2double(mfadd(double2mf(1e-18),double2mf(2e-18))));
  86. printf("1e-16 + 1e-18 = %e\n", mf2double(mfadd(double2mf(1e-16),double2mf(1e-18))));
  87.  
  88. return 0;
  89. }
  90.  
Success #stdin #stdout 0s 1832KB
stdin
Standard input is empty
stdout
1.000000e-18 -> 0x459392 -> 9.999753e-19
2.500000e-01 -> 0x7F8000 -> 2.500000e-01
3.333333e-01 -> 0x7FAAAA -> 3.333282e-01
5.000000e-01 -> 0x808000 -> 5.000000e-01
1.000000e+00 -> 0x818000 -> 1.000000e+00
2.000000e+00 -> 0x828000 -> 2.000000e+00
3.141593e+00 -> 0x82C90F -> 3.141541e+00
1.000000e+18 -> 0xBCDE0B -> 9.999926e+17
300 * 5 = 1.500000e+03
500 + 3 = 5.030000e+02
1e18 * 1e-18 = 9.999390e-01
1e-18 + 2e-18 = 2.999926e-18
1e-16 + 1e-18 = 1.009985e-16