Recent

Author Topic: Why MaxDouble does not equal to MaxDouble?  (Read 2176 times)

jollytall

  • Sr. Member
  • ****
  • Posts: 366
Why MaxDouble does not equal to MaxDouble?
« on: October 04, 2024, 08:45:51 pm »
I have a simple program:
Code: Pascal  [Select][+][-]
  1. uses Math;
  2. var d : double;
  3. begin
  4. d := MaxDouble;
  5. writeln(d, ' ', MaxDouble, ' ', d = MaxDouble);
  6. end.
The result is
Code: [Select]
1.7976931348623157E+308  1.79769313486231569996E+0308 FALSE

Why is MaxDouble shown as E+0308, when even in the source it is defined as
Code: Pascal  [Select][+][-]
  1.     const
  2.       { values according to
  3.         https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Double-precision_examples
  4.       }
  5.       MinDouble    =  2.2250738585072014e-308;
  6.       MaxDouble    =  1.7976931348623157e+308;
What is the best way to have a standard, built-in rarely used number to indicate that the number is not really used?

Warfley

  • Hero Member
  • *****
  • Posts: 1763
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #1 on: October 04, 2024, 09:14:41 pm »
Thats the great thing about untyped constants, for floats they always are interpreted as extended. So when you put it into a double, it will get converted to double. When you than compare the double against the constant, the double will be promoted to extended. This double (pun intended) conversion creates rounding errors.

jollytall

  • Sr. Member
  • ****
  • Posts: 366
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #2 on: October 04, 2024, 09:55:34 pm »
It is clear, but then I would consider it a bug. Shouldn't unit Math has it like:
Code: Pascal  [Select][+][-]
  1. const MaxDouble : double = 1.7976931348623157e+308;


Warfley

  • Hero Member
  • *****
  • Posts: 1763
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #3 on: October 04, 2024, 10:05:59 pm »
This introduces a memory object (typed consts are objects in the executable, while untyped are just "macros" that are replaced by the compiler at compiletime), I think the correct way would be:
Code: Pascal  [Select][+][-]
  1.     const MaxDouble = Double(1.7976931348623157e+308);

jollytall

  • Sr. Member
  • ****
  • Posts: 366
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #4 on: October 04, 2024, 10:13:42 pm »
Oh, yes, that's how it should be.

Zoran

  • Hero Member
  • *****
  • Posts: 1882
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #5 on: October 05, 2024, 12:03:21 am »
Instead of old Math.MaxDouble, use Double.MaxValue. You only need SysUtils in uses, for type helper. It is declared as typed constant:
https://www.freepascal.org/docs-html/current/rtl/sysutils/tdoublehelper.maxvalue.html
« Last Edit: October 05, 2024, 12:05:40 am by Zoran »

mtrsoft

  • New Member
  • *
  • Posts: 49
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #6 on: October 05, 2024, 07:38:52 am »
The above replies are all correct.

A few additional minor observations.

1. You are running Windows x86 which supports the FPU and the Extended type.

2. On Windows x64 and 64 bit apps the Extended type is an alias for the Double type so there shouldn't be an issue.

3. One reason for sticking with 32-bit apps is that the Extended type and FPU are supported.

4. The Extended type has 19 to 20 significant digits whle the Double type has only 14 to 15 significant digits. (I know most people seldom need that many sig. fig., but....)

5. The Extended type has a greater dynamic range of a bit more the e+/-4000. (Again, not often needed, but can be useful.)

John

jollytall

  • Sr. Member
  • ****
  • Posts: 366
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #7 on: October 05, 2024, 09:40:23 am »
I actually use Linux 64 bit, and I always use Double as my "standard" floating point type (maybe a bad practice? thoughts?). Double should be by definition 64 bits, shouldn't it? Extended can be 80 bits on x64, so how could they be the same under Windows?

A related question: I also use Integer as my "standard" integer type as an old habit. Is it actually slower than using Int64 on an x64 platform, or does not matter? As Integer is a variable type being SmallInt or LongInt based on the processor (16bit or 32 or more bits), shouldn't it be "even more variable", being SmallInt (16bit), LongInt(32bit) or Int64(64bit) depending on the system?

Warfley

  • Hero Member
  • *****
  • Posts: 1763
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #8 on: October 05, 2024, 11:59:53 am »
1. You are running Windows x86 which supports the FPU and the Extended type.

2. On Windows x64 and 64 bit apps the Extended type is an alias for the Double type so there shouldn't be an issue.

Depending on your FPC configuration, the fpc can simulate 80bit float operations in software if no FPU support is available, so this is not necessarily true.

tetrastes

  • Hero Member
  • *****
  • Posts: 600
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #9 on: October 05, 2024, 01:08:44 pm »
1. You are running Windows x86 which supports the FPU and the Extended type.

2. On Windows x64 and 64 bit apps the Extended type is an alias for the Double type so there shouldn't be an issue.

Depending on your FPC configuration, the fpc can simulate 80bit float operations in software if no FPU support is available, so this is not necessarily true.

Really? I would prefer that fpc uses 80 bit float operations at win64, where x87 fpu is present. May be you know how to configure this? 

BrunoK

  • Hero Member
  • *****
  • Posts: 623
  • Retired programmer
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #10 on: October 05, 2024, 01:11:33 pm »
The above replies are all correct.
2. On Windows x64 and 64 bit apps the Extended type is an alias for the Double type so there shouldn't be an issue.

3. One reason for sticking with 32-bit apps is that the Extended type and FPU are supported.

4. The Extended type has 19 to 20 significant digits whle the Double type has only 14 to 15 significant digits. (I know most people seldom need that many sig. fig., but....)

5. The Extended type has a greater dynamic range of a bit more the e+/-4000. (Again, not often needed, but can be useful.)
FPC x86_64 for Windows has crippled the possibilities of the x86_64 processor suppressing the precision of 80 bits floats as described in
https://en.wikipedia.org/wiki/Extended_precision, search paragraph x86 extended precision format.
The wrong assessment of the specifics of 80 bits FPU usage led to the WRONG multiplications of currencies for large values on the windows x86_64 64 bit platform. 

Thaddy

  • Hero Member
  • *****
  • Posts: 16199
  • Censorship about opinions does not belong here.
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #11 on: October 05, 2024, 01:17:37 pm »
Florian did give some instructions on how to build FPC Win64 with 80 bit float support a very, very, very long time ago.
But you can run into trouble soon, because the Win64 ABI expects extended to be double!

https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170

A small amount of work has been done to provide 128, 256 and 512 bit return types for floating point operations, so it is certainly possible to write code with a much higher precision than 80 bits.
At the moment that requires inline assembler, though, afaik.
See the details in the link.
« Last Edit: October 05, 2024, 01:37:09 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

tetrastes

  • Hero Member
  • *****
  • Posts: 600
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #12 on: October 05, 2024, 02:15:05 pm »
Strange, but I don't run into trouble with gcc.
I don't understand why fpc team took such decision. At least, they could suggest another option for users.
I think, that the same numerical code giving different results at x86_64-win64 and x86_64-linux is not good. 

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11947
  • FPC developer.
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #13 on: October 05, 2024, 02:23:09 pm »
I actually use Linux 64 bit, and I always use Double as my "standard" floating point type (maybe a bad practice? thoughts?). Double should be by definition 64 bits, shouldn't it? Extended can be 80 bits on x64, so how could they be the same under Windows?

Windows x86_64 ABI deprecated the x87 CPU, and specifies to use SSE2 for floating point.

BrunoK

  • Hero Member
  • *****
  • Posts: 623
  • Retired programmer
Re: Why MaxDouble does not equal to MaxDouble?
« Reply #14 on: October 05, 2024, 02:54:30 pm »
Florian did give some instructions on how to build FPC Win64 with 80 bit float support a very, very, very long time ago.
Where, link please.
Quote
But you can run into trouble soon, because the Win64 ABI expects extended to be double!

https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170

Sorry, this article does not push out anything related to the x87. It specifies how and in which order parameters are passed to sytem calls, how they are aligned. It tells about how the 87 FPU registers must be handled.

As a matter of fact, 87 FPU are inlined to the code stream and NOT passed to the OS.

The only ABI convention that would be of FPC consideration is that the Extended type should be stored on a 16 byte alignment with byte9 at memory byte15 offset if calling the system, but there are no (to my knowledge) 64 bit window calls using EXTENDED.

We are in a situation were progress is REGRESSION !

 

TinyPortal © 2005-2018