Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2010-02

floating point an FPC

10 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

ik

Hello,

I've made a small test:

if (0.1+0.2) = 0.3 then

The only compiler/interpator that actually tells that it equal is FPC.

I've tested it using Javascript (in Firefox), Ruby, Python, C (gcc) and Perl.

Except FPC, everyone tells that 0.1+0.2 = 0.30000000000000004

Can someone explain how FPC see the result and why others does not see it like that ?

Thanks,
Ido

http://ik.homelinux.org/

Reply by email

Marco van de Voort
to ik

In our previous episode, ik said:

Show quoted text 13 lines
I've made a small test: if (0.1+0.2) = 0.3 then The only compiler/interpator that actually tells that it equal is FPC. I've tested it using Javascript (in Firefox), Ruby, Python, C (gcc) and Perl. Except FPC, everyone tells that 0.1+0.2 = 0.30000000000000004 Can someone explain how FPC see the result and why others does not see it like that ?

Extended suport?

Reply by email

Jonas Maebe
to ik: I've made a small test: if (0.1+0.2) = 0.3 then The only compiler/interpator that…
ik wrote 5 lines
I've made a small test: if (0.1+0.2) = 0.3 then The only compiler/interpator that actually tells that it equal is FPC.

Then you are very lucky that FPC says it is equal.

I've tested it using Javascript (in Firefox), Ruby, Python, C (gcc) and Perl.

They are just as correct as FPC.

Except FPC, everyone tells that 0.1+0.2 = 0.30000000000000004

And that answer is also correct.

Can someone explain how FPC see the result and why others does not see it like that ?

It's because of the way floating point works. Read e.g. http://www.lahey.com/float.htm

Jonas

Reply by email

Jerry
to ik: I've made a small test: if (0.1+0.2) = 0.3 then The only compiler/interpator that…

Don't compare floating points. Ever. Now you see why.

Also, don't write loops that calculate a floating point number which is then tested for equality to exit the loop. Also, it is a bad idea to test for > or < for exiting unless you know in advance an accidental equality result will not yield surprising results. In other other words, don't do that (test for > or <) either.

Jerry

ik wrote 24 lines
Hello, I've made a small test: if (0.1+0.2) = 0.3 then The only compiler/interpator that actually tells that it equal is FPC. I've tested it using Javascript (in Firefox), Ruby, Python, C (gcc) and Perl. Except FPC, everyone tells that 0.1+0.2 = 0.30000000000000004 Can someone explain how FPC see the result and why others does not see it like that ? Thanks, Ido http://ik.homelinux.org/ _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

ik
to Jerry

http://ik.homelinux.org/

Jerry wrote
Don't compare floating points. Ever. Now you see why.

So if I need for example to compare currency or something that is floating point, how do I do that ?

Show quoted text 7 lines
Also, don't write loops that calculate a floating point number which is then tested for equality to exit the loop. Also, it is a bad idea to test for > or < for exiting unless you know in advance an accidental equality result will not yield surprising results. In other other words, don't do that (test for > or <) either.

As I understand, there is an old way to calculate floating point that is very popular and newer ways for that.
The old way uses binary calculation and the newer I do not understand them :)

Show quoted text 36 lines
Jerry On Feb 26, 2010, at 3:37 AM, ik wrote: Hello, I've made a small test: if (0.1+0.2) = 0.3 then The only compiler/interpator that actually tells that it equal is FPC. I've tested it using Javascript (in Firefox), Ruby, Python, C (gcc) and Perl. Except FPC, everyone tells that 0.1+0.2 = 0.30000000000000004 Can someone explain how FPC see the result and why others does not see it like that ? Thanks, Ido http://ik.homelinux.org/ _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Ido

Reply by email

Jonas Maebe
to ik
ik wrote
So if I need for example to compare currency or something that is floating point, how do I do that ?

If it's currency, use the currency type. The currency type is fixed point, not floating point, and that's exactly because floating point is inexact while fixed point is not.

If you have to compare actual floating point values, then you have to realise from the start that your comparison will be inexact. That's why there are functions such as math.SameValue() that allow you to specify the precision to use when determining whether or not two values are "the same".

Jonas

Reply by email

Jerry
to ik: http://ik.homelinux.org/ So if I need for example to compare currency or something that…
ik wrote 21 lines
http://ik.homelinux.org/ On Mon, Mar 1, 2010 at 23:20, Jerry wrote: Don't compare floating points. Ever. Now you see why. So if I need for example to compare currency or something that is floating point, how do I do that ? Also, don't write loops that calculate a floating point number which is then tested for equality to exit the loop. Also, it is a bad idea to test for > or < for exiting unless you know in advance an accidental equality result will not yield surprising results. In other other words, don't do that (test for > or <) either. As I understand, there is an old way to calculate floating point that is very popular and newer ways for that. The old way uses binary calculation and the newer I do not understand them :)

The older way that you are thinking of might be binary coded decimal, BCD, in which each decimal digit is represented by its own bit string, usually four bits, to represent the digits 0–9. It is rarely used any more. I'm not sure but maybe Hewlett-Packard calculators use BCD. (HP calculators are known for their excellent numerical accuracy. The academic who did a lot of their work was also involved in the IEEE 754 standard, I think.)

The newer way that you are thinking of is probably IEEE 754 floating point which is implemented widely on modern microprocessors. Its whole numbers (1.0, 2.0, etc.) are supposedly exact equivalents to integer counterparts up to a very large number, but you had _really_ better know what you are doing if you depend on that for comparisons. And expect portability problems when moving to non-IEEE 754 platforms.

BTW, the way to write a loop that increments a floating point number properly is this (Please pardon if any Ada syntax slips in here):

for i := 0 .. 100 begin
	a_float := 1.23 * i;
end;

whereas this is a bad idea:

a := 0.0;
while a <= 100.0 do
	a_float := 1.23 * i;
	a := a + 1.0;
end;

as is this:

a := 0.0;
while a <= 123.0 do
	a := a + 1.23;
end;

Jerry

Show quoted text 43 lines
Jerry On Feb 26, 2010, at 3:37 AM, ik wrote: > Hello, > > I've made a small test: > > if (0.1+0.2) = 0.3 then > > The only compiler/interpator that actually tells that it equal is > FPC. > > I've tested it using Javascript (in Firefox), Ruby, Python, C (gcc) > and Perl. > > Except FPC, everyone tells that 0.1+0.2 = 0.30000000000000004 > > Can someone explain how FPC see the result and why others does not > see it like that ? > > > Thanks, > Ido > > http://ik.homelinux.org/ > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal Ido _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Marco van de Voort
to Jerry

In our previous episode, Jerry said:

I'm not sure but maybe Hewlett-Packard calculators use BCD. (HP calculators are known for their excellent numerical accuracy.

Yes, at least the Saturn based ones do IIRC. They have 64-bit (16 digit) copro registers as you can see here:

http://en.wikipedia.org/wiki/HP_Saturn_%28microprocessor%29

What's not in the link, but from my aging memory is that they can combine two registers to achieve higher precision.

There are more odd things in the HP system btw, the whole HP firmware is nibble based, like the CPU, and when you call "bytes free", it might sometimes return "xx.5" :-)

Reply by email

Graeme Geldenhuys
to ik: http://ik.homelinux.org/ So if I need for example to compare currency or something that…
ik wrote
So if I need for example to compare currency or something that is floating point, how do I do that ?

I think the Currency type is ok (special case with special handling), but other floating types are not.

Alternatively, work with Integer types only, and then when you need to display currency or float with decimal values, do a (x div 100) etc. depending on the size of decimal you want.

All our currency and float values are actually stored as integer inside databases too.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

Flávio Etrusco
to ik: http://ik.homelinux.org/ So if I need for example to compare currency or something that…
ik wrote 11 lines
http://ik.homelinux.org/ On Mon, Mar 1, 2010 at 23:20, Jerry wrote: > > Don't compare floating points. Ever. Now you see why. So if I need for example to compare currency or something that is floating point, how do I do that ?

Let me my 2cent obvious comments too:

1) Just in case you don't know, Curreny is ok in the sense that it's exact - ok, FP is exact in it's own way ;) -, but keep in mind that its precision is just 4 decimal places, so you must be aware of precision loss too.

2) You can determine what is "close enough" for your comparison and use Abs(A - B) < MarginOfError (and of course variants of that code). I vaguely remember some performance problem with Abs (in Delphi or in general? does FP have a signal bit?), so let someone expert chime in to say whether you should Abs or two comparisons intead ;-)

Best regards,
Flávio

Reply by email