genffp.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * GTools C compiler
  3. * =================
  4. * source file :
  5. * Fast Floating-Point generator
  6. *
  7. * Copyright 2001-2004 Paul Froissart.
  8. * Credits to Christoph van Wuellen and Matthew Brandt.
  9. * All commercial rights reserved.
  10. *
  11. * This compiler may be redistributed as long there is no
  12. * commercial interest. The compiler must not be redistributed
  13. * without its full sources. This notice must stay intact.
  14. */
  15. /*
  16. * The following floating-point operations are needed in this module:
  17. *
  18. * - comparision with 0.0, 0.5 and 1.0 - division by 2.0 - multiplication with
  19. * 2.0 (performed as addition here) - subtraction of 1.0
  20. */
  21. #ifndef NOFLOAT
  22. #ifdef PC
  23. #include "define.h"
  24. _FILE(__FILE__)
  25. #ifndef BCDFLT
  26. unsigned long double2ffp(double d) {
  27. unsigned long mantissa;
  28. int sign = 0, exponent = 64, i;
  29. if (d < 0.0) {
  30. sign = 128;
  31. d = -d;
  32. }
  33. while (d < 0.5) {
  34. d += d;
  35. --exponent;
  36. if (exponent == 0)
  37. return sign; /* zero fp number */
  38. }
  39. while (d >= 1.0) {
  40. d /= 2.0;
  41. ++exponent;
  42. if (exponent >= 127)
  43. return 127 + sign; /* +/- infinity */
  44. }
  45. /* 0.5 <=d <1.0 now: construct the mantissa */
  46. mantissa = 0;
  47. for (i = 0; i < 24; i++) {
  48. /* 24 mantissa bits */
  49. d += d;
  50. mantissa = mantissa + mantissa;
  51. if (d >= 1.0) {
  52. ++mantissa;
  53. d -= 1.0;
  54. }
  55. }
  56. /* round up, if the next bit would be 1 */
  57. if (d >= 0.5)
  58. ++mantissa;
  59. /* check on mantissa overflow */
  60. if (mantissa > 0xFFFFFF) {
  61. ++exponent;
  62. /* exponent overflow? */
  63. if (exponent >= 127)
  64. return (127 + sign);
  65. mantissa >>= 1;
  66. }
  67. /* put the parts together and return the value */
  68. return (mantissa << 8) + sign + exponent;
  69. }
  70. #else
  71. void double2bcd(double d,struct bcd *bcd) {
  72. unsigned char *mantptr=bcd->mantissa;
  73. int bias = 16384, exponent = 0, i;
  74. if (d < 0.0) {
  75. bias += 32768;
  76. d = -d;
  77. }
  78. if (d != 0.0) {
  79. while (d < 1.0) {
  80. d *= 10.0;
  81. --exponent;
  82. if (exponent < -999) {
  83. d = 0.0;
  84. break;
  85. }
  86. }
  87. }
  88. while (d >= 10.0) {
  89. d /= 10.0;
  90. ++exponent;
  91. }
  92. if (d==0.0) {
  93. bcd->exponent=16384;
  94. memset(bcd->mantissa,0,BCDLEN);
  95. return;
  96. }
  97. /* 1.0 <= d < 10.0 now: construct the mantissa */
  98. d += 5e-16; /* round up now */
  99. for (i = 0; i < BCDLEN; i++) {
  100. unsigned char digit,buffer;
  101. /* 8 mantissa groups of 2 digits */
  102. if (d>=5.0) {
  103. if (d>=7.0) {
  104. if (d>=8.0) {
  105. if (d>=9.0)
  106. digit=9;
  107. else digit=8;
  108. } else digit=7;
  109. } else if (d>=6.0)
  110. digit=6;
  111. else digit=5;
  112. } else {
  113. if (d>=2.0) {
  114. if (d>=3.0) {
  115. if (d>=4.0)
  116. digit=4;
  117. else digit=3;
  118. } else digit=2;
  119. } else if (d>=1.0)
  120. digit=1;
  121. else digit=0;
  122. }
  123. d -= digit;
  124. d *= 10.0;
  125. buffer = digit<<4;
  126. if (d>=5.0) {
  127. if (d>=7.0) {
  128. if (d>=8.0) {
  129. if (d>=9.0)
  130. digit=9;
  131. else digit=8;
  132. } else digit=7;
  133. } else if (d>=6.0)
  134. digit=6;
  135. else digit=5;
  136. } else {
  137. if (d>=2.0) {
  138. if (d>=3.0) {
  139. if (d>=4.0)
  140. digit=4;
  141. else digit=3;
  142. } else digit=2;
  143. } else if (d>=1.0)
  144. digit=1;
  145. else digit=0;
  146. }
  147. d -= digit;
  148. d *= 10.0;
  149. *mantptr++ = buffer | digit;
  150. }
  151. /* put the parts together and return the value */
  152. bcd->exponent = exponent+bias;
  153. return;
  154. }
  155. #endif /* !defined(BCDFLT) */
  156. #endif /* defined(PC) */
  157. #endif /* !defined(NOFLOAT) */
  158. // vim:ts=4:sw=4