123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- {$IFNDEF FPC_DOTTEDUNITS}
- unit Real48Utils;
- {$ENDIF FPC_DOTTEDUNITS}
- {$mode objfpc}{$H+}
- interface
- type
- { Over 32 bits does not work }
- //TBit52 = 0..$FFFFFFFFFFFFF; { (1 shl 52) - 1 }
- //TBit40 = 0..$FFFFFFFFFF; { (1 shl 40) - 1 }
- //TBit39 = 0..$7FFFFFFFFF; { (1 shl 39) - 1 }
- TBit32 = 0..$FFFFFFFF; { (1 shl 32) - 1 }
- TBit20 = 0..(1 shl 20) - 1;
- TBit11 = 0..(1 shl 11) - 1;
- TBit07 = 0..(1 shl 07) - 1;
- TBit01 = 0..(1 shl 01) - 1;
- //Double
- //S1 E11[Bias $3FF] F52
- TDoubleRec = bitpacked record
- { F:TBit52; }
- F2:TBit20;
- F1:TBit32;
- E:TBit11;
- S:TBit01;
- end;
- PDoubleRec = ^TDoubleRec;
- //Real48
- //S1 F39 E8[Bias 129]
- TReal48Rec = bitpacked record
- E:Byte;
- { F:TBit39; }
- F2:TBit07;
- F1:TBit32;
- S:TBit01;
- end;
- PReal48Rec = ^TReal48Rec;
- function Double2Real(d : double) : real48;
- operator explicit (r:Real48) d:double; inline;
- operator explicit (d:double) r:Real48; inline;
- operator := (d:double) r:real48; inline;
- operator := (r:real48) d:double; inline;
- operator +(const r1:Real48) r:Real48;inline;
- operator +(const r1:Real48;const r2:Real48) r:Real48;inline;
- operator -(const r1:Real48) r:Real48;inline;
- operator -(const r1:Real48;const r2:Real48) r:Real48;inline;
- operator *(const r1:Real48;const r2:Real48) r:Real48;inline;
- operator /(const r1:Real48;const r2:Real48) r:Real48;inline;
- operator =(const r1:Real48;const r2:Real48) b:boolean;inline;
- operator <(const r1:Real48;const r2:Real48) b:boolean;inline;
- operator >(const r1:Real48;const r2:Real48) b:boolean;inline;
- operator >=(const r1:Real48;const r2:Real48) b:boolean;inline;
- operator <=(const r1:Real48;const r2:Real48) b:boolean;inline;
- implementation
- function Double2Real(d : double) : real48;
- var
- res : array[0..5] of byte;
- rrec:TReal48Rec absolute res;
- drec:TDoubleRec absolute d;
- begin
- { copy mantissa }
- rrec.F1 := drec.F1;
- rrec.F2 := drec.F2 shr 13;
- { copy exponent }
- { correct exponent: }
- if drec.E<>0 then
- rrec.E := drec.E - 1023 + 129
- else
- rrec.E:=0; // signed zero exception. Note E=2047=inf.
- { set sign }
- rrec.S := drec.S;
- double2real:=res;
- end;
- operator explicit (r:Real48) d:double;inline;
- begin
- d := Real2Double(r);
- end;
- operator explicit (d:double) r:Real48;inline;
- begin
- r := Double2Real(d);
- end;
- operator := (d:double) r:real48; inline;
- begin
- r := Double2Real(d);
- end;
- operator := (r:real48) d:double; inline;
- begin
- d := Real2Double(r);
- end;
- operator +(const r1:Real48;const r2:Real48) r:Real48;inline;
- begin
- r := double(r1)+double(r2);
- end;
- operator -(const r1:Real48) r:Real48;inline;
- begin
- r := -double(r1);
- end;
- operator +(const r1:Real48) r:Real48;inline;
- begin
- r := double(r1);
- end;
- operator -(const r1:Real48;const r2:Real48) r:Real48;inline;
- begin
- r := double(r1)-double(r2);
- end;
- operator *(const r1:Real48;const r2:Real48) r:Real48;inline;
- begin
- r := double(r1)*double(r2);
- end;
- operator /(const r1:Real48;const r2:Real48) r:Real48;inline;
- begin
- r := double(r1)/double(r2);
- end;
- operator =(const r1:Real48;const r2:Real48) b:boolean;inline;
- begin
- b := double(r1)=double(r2);
- end;
- operator <(const r1:Real48;const r2:Real48) b:boolean;inline;
- begin
- b := double(r1)<double(r2);
- end;
- operator >(const r1:Real48;const r2:Real48) b:boolean;inline;
- begin
- b := double(r1)>double(r2);
- end;
- operator >=(const r1:Real48;const r2:Real48) b:boolean;inline;
- begin
- b := double(r1)>=double(r2);
- end;
- operator <=(const r1:Real48;const r2:Real48) b:boolean;inline;
- begin
- b := double(r1)<=double(r2);
- end;
- end.
|