3

The unit System.Math defines the constant

MinExtended80Denormal

Can I convert this number to string with the given rtl functions?

I tried

FormatFloat('#.##############E+####', System.math.MinExtended80Denormal)

which results in

000000000000000E+00000

I tried larger denormalized values too, but it seems that such values (in which the exponent is zero) are not supported by the built-in formatting functions.

J...
  • 30,968
  • 6
  • 66
  • 143
ventiseis
  • 3,029
  • 11
  • 32
  • 49
  • 2
    For me, `FormatFloat()` returns `0E+0` instead. But either way, I can reproduce the issue. Must be a bug in `FormatFloat()` for scientific output – Remy Lebeau Mar 28 '18 at 01:12
  • 1
    Why are you asking? Do you want to represent this specific value as text, or do you want to represent arbitrary denormals as text? – David Heffernan Mar 28 '18 at 06:29
  • I assume that the minimum Extended 80 denormal is so small, that it is very close to 0 (probably just oine bit in the mantissa), so you won't be able to format it with FormatFloat. – Rudy Velthuis Mar 28 '18 at 10:16
  • I'm presuming this is Tokyo - I don't think that constant is defined in versions prior. – J... Mar 28 '18 at 13:01
  • That said, it seems the real issue here, as David suggested, is that *all denormals*, generally, will not format correctly with `Format`, `FormatFloat`, `FloatToStr` or related functions, not just this specific constant. – J... Mar 28 '18 at 14:58
  • @DavidHeffernan I'm asking because looked at the `PUREPASCAL` implementation of `System.Math.Log10(Extended)` and found a constant array of word named `InvLn10`. Using that value, `FormatFloat` prints `?,?<` which is even stranger. As I can not publish code from the rtl here (licensing!), I tested a few other values and found the described behavior. I was hoping to get some insights here. – ventiseis Mar 28 '18 at 17:30
  • @Rudy That doesn't make a lot sense. Clearly there is just a single bit set in the significant. That's the very definition of the smallest denormal. Why that should make a function unable to convert to decimal text isn't at all clear from what you wrote. There are plenty of functions that can. You seem to have simply written down the obvious, and restated the facts of the question. – David Heffernan Mar 29 '18 at 07:11
  • @vent Why are you interested in 80 bit floats? They are somewhat discredited these days. You only find them on Intel platforms. They are not used by 64 bit compilers. Modern processors are dedicated fewer resources to the x87 unit concentrating instead on SSE. – David Heffernan Mar 29 '18 at 07:14
  • @David: fact is that FormatFloat (and ToString, etc.) return 0. That means, to me, that these functions do not handle denormals (or at least this one) properly or at least as "denormal-as-zero" (DAZ). – Rudy Velthuis Mar 29 '18 at 18:00
  • @Rudy Yes. That's stated in the question. The asker wants to know how to format such values. The asker already knows what you are saying. Simply repeating the facts manifest from the question is a waste of time. – David Heffernan Mar 29 '18 at 18:06
  • @David: The asker already has an answer. I am merely trying to find out why this is. – Rudy Velthuis Mar 29 '18 at 18:30
  • @rudy No you aren't. Point to the part where you made an effort to explain anything. – David Heffernan Mar 29 '18 at 21:57
  • 1
    @David: I think I know best what I am trying to find out. I never said I had an explanation already. These are comments, not answers. – Rudy Velthuis Mar 30 '18 at 08:34

1 Answers1

4

Using the System built in printing functions it works:

uses
  Math;
var
  s:String;
begin
  Str(MinExtended80Denormal,s);
  WriteLn(s);
  WriteLn(MinExtended80Denormal);
  Str(MinExtended80Denormal:26:-1,s);
  WriteLn(s);
  WriteLn(MinExtended80Denormal:26:-1);
end.

Outputs:

3.64519953188247E-4951
3.64519953188247E-4951
3.64519953188247460E-4951
3.64519953188247460E-4951

The constant MinExtended80Denormal is defined as: 3.64519953188247460253e-4951 So the best result gives all digits but the last three decimals.


I also tried WriteLn(MinExtended80Denormal.ToString), but that gave 0.

LU RD
  • 34,438
  • 5
  • 88
  • 296
  • Given that this is the minimum denormal, there's little point in getting exercised about how many decimal places are output. You've lost all precision with all those zeros at the front of the significand! – David Heffernan Mar 28 '18 at 08:18
  • 1
    @DavidHeffernan, still it would be good if there was a reversible possibility (going from value to text and back to value). I don't know if this important for the OP, though. – LU RD Mar 28 '18 at 09:16
  • 1
    @LURD Roundtrip formatting (i.e. format thus that if the output is read in again, you get the same value, and also thus that no more digits are output as is necessary to get the value back) is not so easy, especially not for such enormously small values. I doubt the System or Math routines are capable of it. Roundtrip formatting is usually slower too, although progress has been made in that field. – Rudy Velthuis Mar 28 '18 at 10:20
  • ToString probably uses FormatFloat (can't check here). – Rudy Velthuis Mar 28 '18 at 10:22
  • @LURD I changed code from [another float point formatting library](http://www.ryanjuckett.com/programming/printing-floating-point-numbers/part-2/) and wanted to compare it with the results from Delphi as is supports 80-bit floating point values out of the box. – ventiseis Mar 28 '18 at 17:37
  • @RudyVelthuis At least in Delphi Seattle it uses `FloatToStr` and `FloatToStrF`. – ventiseis Mar 28 '18 at 17:39
  • 1
    @LURD: An output of 4e-4951 would roundtrip too, i.e. give you the value hex $0000000000000001 again. So you really don't need a lot of *precision* to roundtrip. The goal of roundtrip formatting is to output the least precision (the smallest number of digits) necessary to get the result back. – Rudy Velthuis Mar 28 '18 at 23:14
  • 1
    Python is a useful tool to understand round tripping. Its formatting routines output the shortest number of significant digits required to uniquely define the value. Do that with the min denormal and you get a single significant digit. – David Heffernan Mar 29 '18 at 18:07