var
A, B extended;
TheStr : string;
begin
A := FunctionReturningAFloat;
TheStr := FloatToStr(A);
B := StrToFloat(TheStr);
Assert(A = B);
end;
..Assert never raises an exception?
I ask the question as I want to run a long numerical simulation with an
option to stop calculation and save all variables and the status of the
calculation to a text file, at any point in time. Then I can reload and
run from the stopping point (either to the conclusion of the calculation
or to another stopping point) when more processor time is available. I
need to guarantee that this process will provide the same final result
as running to completion in a single stage.
Mike
No. The binary number base is 2, the string number base is 10, and there
can not exist an exact conversion between both bases.
DoDi
It will raise exception in many cases when real value can be expressed
in string. for example try "A := 2/3" in first line.
> I ask the question as I want to run a long numerical simulation with an
> option to stop calculation and save all variables and the status of the
> calculation to a text file, at any point in time. Then I can reload and
> run from the stopping point (either to the conclusion of the calculation
> or to another stopping point) when more processor time is available. I
> need to guarantee that this process will provide the same final result
> as running to completion in a single stage.
>
I do not know how You want to save values, but best way is to do it
binary (save bits). This way You can save values like infinity, NAN, +0
and -0.
Here is some example and test procedure
procedure TForm1.Button1Click(Sender: TObject);
procedure test(f1: extended);
var
f2: extended;
ms: TMemoryStream;
begin
memo1.lines.add(FloatToStr(f1));
ms := TMemoryStream.Create();
//write float
ms.WriteBuffer(f1, sizeof(extended));
//rewind stream
ms.position := 0;
//read float
ms.ReadBuffer(f2, sizeof(extended));
//check
if f1 = f2 then memo1.lines.add('equal')
else memo1.lines.add('NOT equal');
ms.free();
end;
begin
test(2/3);
test(1/3);
test(1/15);
test(((0.0 + maxint) * maxint) / 15);
test(((0.0 + maxint) * maxint* maxint* maxint));
test(1/0.000000000000000000000001);
end;
If You really must save to text file, then i suggest You to base64
encode binary stream.
--
Arivald
Yes there can. Every base 2 number can be represented precisely in base
10. The resulting base 10 number (but not an arbitrary base 10 number)
can then be converted losslessly back into base 2.
Cheers,
Nicholas Sherlock
Note that despite this, I don't think that either FloatToStr or
StrToFloat will give exact results. You can convert a float to a decimal
string precisely with John Herbster's "ExactFloatToStr":
http://cc.embarcadero.com/Item.aspx?id=19421
Cheers,
Nicholas Sherlock
>> No. The binary number base is 2, the string number base is 10, and
>> there can not exist an exact conversion between both bases.
>
> Yes there can. Every base 2 number can be represented precisely in base
> 10. The resulting base 10 number (but not an arbitrary base 10 number)
> can then be converted losslessly back into base 2.
Sounds reasonable, but I'm not so sure. Successive divisions by 10, as
required by the conversion into decimal format, IMO can result in
rounding errors in the FPU.
With the binary mantissa bits representing powers of 2, i.e. 1/2, 1/4,
1/8 etc., the decimal equivalents were 0.5, 0.25, 0.125, so that the
decimal number must have one decimal digit per binary bit. When
FloatToStr limits the number of digits to less than the number of bits
in the binary representation, the decimal representation is inprecise
and cannot be converted back into the same binary value.
DoDi
>>> No. The binary number base is 2, the string number base is 10, and
>>> there can not exist an exact conversion between both bases.
>>
>> Yes there can. Every base 2 number can be represented precisely in
>> base 10. The resulting base 10 number (but not an arbitrary base 10
>> number) can then be converted losslessly back into base 2.
>
> Note that despite this, I don't think that either FloatToStr or
> StrToFloat will give exact results. You can convert a float to a decimal
> string precisely with John Herbster's "ExactFloatToStr":
>
> http://cc.embarcadero.com/Item.aspx?id=19421
A simple lossless conversion is possible with an variant record,
containing a double and int64 overlay. The decimal representation uses
the int64 value and conversion routines, the binary value can be
exchanged with the variables in the application. No need to deal with
NaN and other special values :-)
DoDi
Yes, but I was talking in general and not about any specific
implementation.
Cheers,
Nicholas Sherlock