Sign in Join

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

Mailing lists / fpc-pascal / 2026-09

Formatting negative zero floating point numbers

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Mark

I have a free pascal and a C program that both generate numeric output in text format. I expect both programs to produce the same output and I automatically verify that with a simple textual diff in my build process. That works fine in general except for negative zero floating point values (https://en.wikipedia.org/wiki/Signed_zero). The issue is that FloatToStrF does not output a minus sign for those values. Here are short examples to reproduce the behavior. The C output is what I would expect.

C:

#include <stdio.h>
int main() {
     double d = -0.0;
     printf("%e\n", d);
     return 0;
}
$ ./main
-0.000000e+00

Pascal (fpc-3.2.2):

program main;
uses
   sysutils;
var
   d :Double;
   s :String;
begin
    d := -0.0;
    Writeln(d);
    WriteStr(s, d);
    Writeln(s);
    Str(d:0:17, s);
    Writeln(s);
    Writeln(FloatToStrF(d, ffExponent, 17, 3));
    Writeln(Format('%e', [d]));
end.

$ ./main
-0.0000000000000000E+000
-0.0000000000000000E+000
-0.00000000000000000
0.0000000000000000E+000
0.0000000000000000E+000

The output of FloatToStrF and Format is different to what I expect and get with C. However, it is also different to what Write/WriteStr/Str produces which seems inconsistent to me. Is that actually the expected behavior? If yes, is there another way to get the desired output? Using WriteStr is no alternative for my use case, since I need control over the number of digits for the exponent.

Thanks,
Mark

Reply by email

Unknown author
to Mark

Have you tried using the Pascal Str() function like so:

var
  num: Integer;
  text: String;
begin
  num := 123;
  Str(num, text); { text now contains '123' }
  Writeln(text);
end.
Earlier message 71 lines
-----Original Message----- From: fpc-pascal On Behalf Of Mark via fpc-pascal Sent: Monday, September 21, 2026 11:31 AM To: Cc: Mark Subject: [fpc-pascal] Formatting negative zero floating point numbers I have a free pascal and a C program that both generate numeric output in text format. I expect both programs to produce the same output and I automatically verify that with a simple textual diff in my build process. That works fine in general except for negative zero floating point values (https://en.wikipedia.org/wiki/Signed_zero). The issue is that FloatToStrF does not output a minus sign for those values. Here are short examples to reproduce the behavior. The C output is what I would expect. C: #include <stdio.h> int main() { double d = -0.0; printf("%e\n", d); return 0; } $ ./main -0.000000e+00 Pascal (fpc-3.2.2): program main; uses sysutils; var d :Double; s :String; begin d := -0.0; Writeln(d); WriteStr(s, d); Writeln(s); Str(d:0:17, s); Writeln(s); Writeln(FloatToStrF(d, ffExponent, 17, 3)); Writeln(Format('%e', [d])); end. $ ./main -0.0000000000000000E+000 -0.0000000000000000E+000 -0.00000000000000000 0.0000000000000000E+000 0.0000000000000000E+000 The output of FloatToStrF and Format is different to what I expect and get with C. However, it is also different to what Write/WriteStr/Str produces which seems inconsistent to me. Is that actually the expected behavior? If yes, is there another way to get the desired output? Using WriteStr is no alternative for my use case, since I need control over the number of digits for the exponent. Thanks, Mark

Reply by email

Mark
to Unknown author
Robert Wolfe wrote
Have you tried using the Pascal Str() function like so:

Yes, that works, but as mentioned, I need control over the number of digits for the exponent. That's why I'm using FloatToStrF.

For now I am working around the issue as follows:

program main;
uses
   sysutils;
function IsNegativeZero(const d: Double): Boolean;
begin
   Result := UInt64(d) = UInt64($8000000000000000);
end;
procedure WriteDoubleValue(var f: TextFile; v: Double);
var
   sign :String;
begin
   if IsNegativeZero(v) then
     sign := '-'
   else
     sign := '';
   // need to use FloatToStrF to change exponent digits from 3 to 2
   Writeln(f, format('%s%s(%16.16x)', [ sign, FloatToStrF(v, ffExponent, 17, 2), UInt64(v) ]));
end;
begin
    WriteDoubleValue(StdOut, 0.0);
    WriteDoubleValue(StdOut, -0.0);
end.

which gives:

0.0000000000000000E+00(0000000000000000)
-0.0000000000000000E+00(8000000000000000)

Any opinion from the fpc/rtl maintainers? Is the behavior of Format and FloatToStrF to omit a minus sign for negative zero values - in contrast to what Write and Str are doing - a bug or not?

Mark

Reply by email