Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

FloattoStr and StrtoFloat - are they exact inverses of each other?

9 views
Skip to first unread message

mike

unread,
Jun 3, 2009, 7:16:29 PM6/3/09
to
Question is in the title. Can I always guarantee that in..

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

Jamie

unread,
Jun 3, 2009, 7:37:31 PM6/3/09
to
Yes, they should be. They both use Extended in the FPU, what you may
want to insure is the FPU controlWord to be the same on each process you
pick up on from PC to PC.


http://webpages.charter.net/jamie_5"

Hans-Peter Diettrich

unread,
Jun 4, 2009, 12:09:51 AM6/4/09
to
mike schrieb:

> Question is in the title. Can I always guarantee that in..
>
> var
> A, B extended;
> TheStr : string;
> begin
> A := FunctionReturningAFloat;
> TheStr := FloatToStr(A);
> B := StrToFloat(TheStr);
> Assert(A = B);
> end;
>
> ...Assert never raises an exception?

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

Arivald

unread,
Jun 4, 2009, 2:09:31 AM6/4/09
to
mike pisze:

> Question is in the title. Can I always guarantee that in..
>
> var
> A, B extended;
> TheStr : string;
> begin
> A := FunctionReturningAFloat;
> TheStr := FloatToStr(A);
> B := StrToFloat(TheStr);
> Assert(A = B);
> end;
>
> ..Assert never raises an exception?

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

Nicholas Sherlock

unread,
Jun 4, 2009, 3:26:03 AM6/4/09
to

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

Nicholas Sherlock

unread,
Jun 4, 2009, 3:28:04 AM6/4/09
to

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

Hans-Peter Diettrich

unread,
Jun 5, 2009, 7:01:38 AM6/5/09
to
Nicholas Sherlock schrieb:

>> 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

Hans-Peter Diettrich

unread,
Jun 5, 2009, 7:44:50 AM6/5/09
to
Nicholas Sherlock schrieb:

>>> 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

Nicholas Sherlock

unread,
Jun 6, 2009, 9:02:38 AM6/6/09
to
Hans-Peter Diettrich wrote:
> Nicholas Sherlock schrieb:
>
>>> 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.


Yes, but I was talking in general and not about any specific
implementation.

Cheers,
Nicholas Sherlock

0 new messages