real48utils.pp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. {$IFNDEF FPC_DOTTEDUNITS}
  2. unit Real48Utils;
  3. {$ENDIF FPC_DOTTEDUNITS}
  4. {$mode objfpc}{$H+}
  5. interface
  6. type
  7. { Over 32 bits does not work }
  8. //TBit52 = 0..$FFFFFFFFFFFFF; { (1 shl 52) - 1 }
  9. //TBit40 = 0..$FFFFFFFFFF; { (1 shl 40) - 1 }
  10. //TBit39 = 0..$7FFFFFFFFF; { (1 shl 39) - 1 }
  11. TBit32 = 0..$FFFFFFFF; { (1 shl 32) - 1 }
  12. TBit20 = 0..(1 shl 20) - 1;
  13. TBit11 = 0..(1 shl 11) - 1;
  14. TBit07 = 0..(1 shl 07) - 1;
  15. TBit01 = 0..(1 shl 01) - 1;
  16. //Double
  17. //S1 E11[Bias $3FF] F52
  18. TDoubleRec = bitpacked record
  19. { F:TBit52; }
  20. F2:TBit20;
  21. F1:TBit32;
  22. E:TBit11;
  23. S:TBit01;
  24. end;
  25. PDoubleRec = ^TDoubleRec;
  26. //Real48
  27. //S1 F39 E8[Bias 129]
  28. TReal48Rec = bitpacked record
  29. E:Byte;
  30. { F:TBit39; }
  31. F2:TBit07;
  32. F1:TBit32;
  33. S:TBit01;
  34. end;
  35. PReal48Rec = ^TReal48Rec;
  36. function Double2Real(d : double) : real48;
  37. operator explicit (r:Real48) d:double; inline;
  38. operator explicit (d:double) r:Real48; inline;
  39. operator := (d:double) r:real48; inline;
  40. operator := (r:real48) d:double; inline;
  41. operator +(const r1:Real48) r:Real48;inline;
  42. operator +(const r1:Real48;const r2:Real48) r:Real48;inline;
  43. operator -(const r1:Real48) r:Real48;inline;
  44. operator -(const r1:Real48;const r2:Real48) r:Real48;inline;
  45. operator *(const r1:Real48;const r2:Real48) r:Real48;inline;
  46. operator /(const r1:Real48;const r2:Real48) r:Real48;inline;
  47. operator =(const r1:Real48;const r2:Real48) b:boolean;inline;
  48. operator <(const r1:Real48;const r2:Real48) b:boolean;inline;
  49. operator >(const r1:Real48;const r2:Real48) b:boolean;inline;
  50. operator >=(const r1:Real48;const r2:Real48) b:boolean;inline;
  51. operator <=(const r1:Real48;const r2:Real48) b:boolean;inline;
  52. implementation
  53. function Double2Real(d : double) : real48;
  54. var
  55. res : array[0..5] of byte;
  56. rrec:TReal48Rec absolute res;
  57. drec:TDoubleRec absolute d;
  58. begin
  59. { copy mantissa }
  60. rrec.F1 := drec.F1;
  61. rrec.F2 := drec.F2 shr 13;
  62. { copy exponent }
  63. { correct exponent: }
  64. if drec.E<>0 then
  65. rrec.E := drec.E - 1023 + 129
  66. else
  67. rrec.E:=0; // signed zero exception. Note E=2047=inf.
  68. { set sign }
  69. rrec.S := drec.S;
  70. double2real:=res;
  71. end;
  72. operator explicit (r:Real48) d:double;inline;
  73. begin
  74. d := Real2Double(r);
  75. end;
  76. operator explicit (d:double) r:Real48;inline;
  77. begin
  78. r := Double2Real(d);
  79. end;
  80. operator := (d:double) r:real48; inline;
  81. begin
  82. r := Double2Real(d);
  83. end;
  84. operator := (r:real48) d:double; inline;
  85. begin
  86. d := Real2Double(r);
  87. end;
  88. operator +(const r1:Real48;const r2:Real48) r:Real48;inline;
  89. begin
  90. r := double(r1)+double(r2);
  91. end;
  92. operator -(const r1:Real48) r:Real48;inline;
  93. begin
  94. r := -double(r1);
  95. end;
  96. operator +(const r1:Real48) r:Real48;inline;
  97. begin
  98. r := double(r1);
  99. end;
  100. operator -(const r1:Real48;const r2:Real48) r:Real48;inline;
  101. begin
  102. r := double(r1)-double(r2);
  103. end;
  104. operator *(const r1:Real48;const r2:Real48) r:Real48;inline;
  105. begin
  106. r := double(r1)*double(r2);
  107. end;
  108. operator /(const r1:Real48;const r2:Real48) r:Real48;inline;
  109. begin
  110. r := double(r1)/double(r2);
  111. end;
  112. operator =(const r1:Real48;const r2:Real48) b:boolean;inline;
  113. begin
  114. b := double(r1)=double(r2);
  115. end;
  116. operator <(const r1:Real48;const r2:Real48) b:boolean;inline;
  117. begin
  118. b := double(r1)<double(r2);
  119. end;
  120. operator >(const r1:Real48;const r2:Real48) b:boolean;inline;
  121. begin
  122. b := double(r1)>double(r2);
  123. end;
  124. operator >=(const r1:Real48;const r2:Real48) b:boolean;inline;
  125. begin
  126. b := double(r1)>=double(r2);
  127. end;
  128. operator <=(const r1:Real48;const r2:Real48) b:boolean;inline;
  129. begin
  130. b := double(r1)<=double(r2);
  131. end;
  132. end.