### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: extended type equality  (Read 2260 times)

#### littlepaul476

• New member
• Posts: 9
##### extended type equality
« on: November 21, 2018, 10:22:43 am »
Can someone explain to me, why this ended with <NOT OK>? Double or Real alternatives are <OK>.

Code: Pascal  [Select][+][-]
1. var i,j: extended;
2. begin
3.   i:=23500.0*0.032;
4.   j:=752.0;
5.   if i=j then
6.     <OK>
7.   else
8.     <NOT OK>;
9. end;

Lazarus 1.8.4. FPC 3.0.4, Win32
« Last Edit: November 21, 2018, 10:24:14 am by littlepaul476 »

#### marcov

• Global Moderator
• Hero Member
• Posts: 8734
• FPC developer.
##### Re: extended type equality
« Reply #1 on: November 21, 2018, 10:28:35 am »
Floating point math is not exact.

Extended on 32-bit x86 has more precision, so the deviation from the exact value suddenly fits extended. If you print i you get

7.51999999999999999944E+0002

There is a lot of information about comparing floating point values on the internet, I suggest you read it for a background.

https://floating-point-gui.de/errors/comparison/
https://bitbashing.io/comparing-floats.html

The common trick is to compare with a small deviation (if abs(x-y)<eps then instead of x=y),   free Pascal has a helper routine for that called samevalue

#### littlepaul476

• New member
• Posts: 9
##### Re: extended type equality
« Reply #2 on: November 21, 2018, 11:28:36 am »
Thanks for explanation. I checked values under Watch List and both i and j showed 752. SameValue did the trick, even with default epsilon = 0

#### wp

• Hero Member
• Posts: 7553
##### Re: extended type equality
« Reply #3 on: November 21, 2018, 11:35:56 am »
SameValue did the trick, even with default epsilon = 0
The default value here is misleading. The value 0 signals to use a standard epsilon depending on the floatingpoint data type. Copied from math.pp:
Code: Pascal  [Select][+][-]
1. Const
2.   EZeroResolution = 1E-16;
3.   DZeroResolution = 1E-12;
4.   SZeroResolution = 1E-4;
5.
6. function SameValue(const A, B: Extended; Epsilon: Extended): Boolean;
7. begin
8.   if (Epsilon=0) then
9.     Epsilon:=Max(Min(Abs(A),Abs(B))*EZeroResolution,EZeroResolution);
10.   if (A>B) then
11.     Result:=((A-B)<=Epsilon)
12.   else
13.     Result:=((B-A)<=Epsilon);
14. end;
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### srvaldez

• New member
• Posts: 5
##### Re: extended type equality
« Reply #4 on: November 21, 2018, 01:38:34 pm »
I played with this for a while
changing the expression i:=23500.0*0.032; to i:=23500.0*32/1000; made it work
I thought that casting the literal constant to extended would work, but it made no difference.

#### PascalDragon

• Hero Member
• Posts: 2156
• Compiler Developer
##### Re: extended type equality
« Reply #5 on: November 21, 2018, 02:40:59 pm »
Simply don't assume that two floating point values are equal (except when checking for special values like 0, +/- Infinity and NaN). Everything else will only lead to problems sooner or later.

#### Gammatester

• Jr. Member
• Posts: 69
##### Re: extended type equality
« Reply #6 on: November 21, 2018, 03:35:31 pm »
Floating point arithmetic works by rounding the true result to the next representable floating point number (using the selected precision and rounding mode).

With double precision you have
Code: [Select]
`0.032 -> 0.03200000000000000066613381477509392425417900085449218750.032*23500 -> 752.00000000000001565414464721470721997320652008056640625`The last number is rounded to 752 and with FPC304/Win7 you really get OK!

OTH, for extended precision you get
Code: [Select]
`0.032 -> 0.031999999999999999998671852338705257068340870318934321403503417968750.032*23500 -> 751.999999999999999968788529959573541106010452494956552982330322265625`The last number is rounded to 751.999999999999999944488848768742172978818416595458984375, and therefore you get NOT OK.

Your expression 23500.0*32/1000 works, because all numbers are (representable as) integers and so the result must be an integer.
« Last Edit: November 21, 2018, 03:52:59 pm by Gammatester »