[fpc-pascal] TFloatHelper.BuildUp() question
Bart
bartjunk64 at gmail.com
Fri Dec 15 13:36:29 CET 2017
Hi,
I think I misunderstand what this procedure is for?
Procedure BuildUp(const ASignFlag: Boolean; const AMantissa: QWord;
const AExponent: Integer);
>From it's signature I would expect that it constructs a float from the
supplied parameters.
I also assumed that this would be reciprocal: if I query Sign,
Mantissa and Exponent from a given float, then uses BuildUp with these
parameters, I would get a float with the original value back:
This however seems not to be the case.
======================
program fl;
{$mode objfpc}
{$h+}
uses
SysUtils;
const
Signs: Array[Boolean] of Char = ('+','-');
function DbgS(E: Extended): String; overload;
begin
Result := 'Sign: ' + Signs[E.Sign] +
' Mantissa: ' + IntToHex(E.Mantissa, SizeOf(E.Mantissa)*2) +
' Exp: ' + IntToHex(E.Exp, SizeOf(E.Exp)*2) +
' Frac: ' + IntToHex(E.Frac, SizeOf(E.Frac)*2);
end;
function DbgS(D: Double): String; overload;
begin
Result := 'Sign: ' + Signs[D.Sign] +
' Mantissa: ' + IntToHex(D.Mantissa, SizeOf(D.Mantissa)*2) +
' Exp: ' + IntToHex(D.Exp, SizeOf(D.Exp)*2) +
' Frac: ' + IntToHex(D.Frac, SizeOf(D.Frac)*2);
end;
function DbgS(S: Single): String; overload;
begin
Result := 'Sign: ' + Signs[S.Sign] +
' Mantissa: ' + IntToHex(S.Mantissa, SizeOf(S.Mantissa)*2) +
' Exp: ' + IntToHex(S.Exp, SizeOf(S.Exp)*2) +
' Frac: ' + IntToHex(S.Frac, SizeOf(S.Frac)*2);
end;
var
E: Extended;
ESign, SSign, DSign: Boolean;
EMant, EExp, EFrac, SMant, SExp, SFrac, DMant, DExp, DFrac: QWord;
S: Single;
D: Double;
begin
writeln('Extended (',SizeOf(Extended),' bytes)');
E := 1.0;
writeln('E = ',E,#32,DbgS(E));
ESign := E.Sign;
EMant := E.Mantissa;
EExp := E.Exp;
EFrac := E.Frac;
E.BuildUp(ESign, EMant, EExp);
writeln('E = ',E,#32,DbgS(E));
writeln;
writeln('Double (',SizeOf(Double),' bytes)');
D := 1.0;
writeln('D = ',D,#32,DbgS(D));
DSign := D.Sign;
DMant := D.Mantissa;
DExp := D.Exp;
DFrac := D.Frac;
D.BuildUp(DSign, DMant, DExp);
writeln('D = ',E,#32,DbgS(D));
writeln;
writeln('Single (',SizeOf(Single),' bytes)');
S := 1.0;
writeln('S = ',S,#32,DbgS(S));
SSign := S.Sign;
SMant := S.Mantissa;
SExp := S.Exp;
SFrac := S.Frac;
S.BuildUp(SSign, SMant, SExp);
writeln('S = ',S,#32,DbgS(S));
writeln;
end.
===========================
Output (tested with 3.0.4 and trunk):
Extended (10 bytes)
E = 1.00000000000000000000E+0000 Sign: + Mantissa: 0000000000000000
Exp: 0000000000003FFF Frac: 8000000000000000
E = Nan Sign: + Mantissa: 0000000000000000 Exp: 00000000000043FE Frac:
0000000000000000
Double (8 bytes)
D = 1.0000000000000000E+000 Sign: + Mantissa: 0000000000000000 Exp:
00000000000003FF Frac: 0010000000000000
D = Nan Sign: + Mantissa: 0000000000000000 Exp: 00000000000007FE Frac:
0010000000000000
Single (4 bytes)
S = 1.000000000E+00 Sign: + Mantissa: 0000000000000000 Exp:
000000000000007F Frac: 0000000008000000
S = 5.000000000E-01 Sign: + Mantissa: 0000000000000000 Exp:
000000000000007E Frac: 0000000008000000
What am I doing wrong here?
Bart
More information about the fpc-pascal
mailing list