View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0018704FPCRTLpublic2011-02-07 10:292012-05-19 16:55
ReporterNukool C. 
Assigned ToFlorian 
PrioritynormalSeveritymajorReproducibilityalways
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product VersionProduct Build 
Target VersionFixed in Version2.7.1 
Summary0018704: CurrToStrF is not equal to FloatToStrF
DescriptionCurrToStrF((1000000-1) / 1826, ffnumber, 4)); //547.6446
CurrToStrF((1000000-1) / 1826, ffnumber, 2)); //547.65 on FPC, 547.64 on Delphi
FloatToStrF((1000000-1) / 1826, ffnumber, 10, 4)); //547.6446
FloatToStrF((1000000-1) / 1826, ffnumber, 10, 2)); //547.64
Additional InformationN/A
Tagscurrency
FPCOldBugId0
Fixed in Revision21339
Attached Files? file icon CurrencyFormatTest.pp [^] (1,678 bytes) 2012-05-06 17:35
? file icon CurrencyFormatTest2.pp [^] (2,349 bytes) 2012-05-07 10:16
patch file icon currency2str_formatting.patch [^] (437 bytes) 2012-05-07 10:16 [Show Content]
patch file icon currency2str_rounding.patch [^] (1,148 bytes) 2012-05-07 10:17 [Show Content]
patch file icon currency2str_formatting_v2.patch [^] (411 bytes) 2012-05-08 07:07 [Show Content]
? file icon CurrencyFormatTest3.pp [^] (3,117 bytes) 2012-05-08 16:36

- Relationships
related to 0022063closedFlorian [Patch] Invalid currency formatting 

-  Notes
(0045869)
Zoran Vučenović (reporter)
2011-02-07 13:48
edited on: 2011-02-07 13:51

CurrToStrF only calls FloatToStrF and FloatToStrF also gives wrong result when called with Currency parameter!
Further, FloatToStrF calls Str function, which also gives wrong result.

Please see this test:

program StrTest;
uses
  sysutils;
var
  C: Currency;
  D: Double;
  S: String;
begin
  C := 1.45;
  D := 1.45;

  WriteLn('Using FloatToStrF:');
  S := FloatToStrF(C, ffNumber, 19, 0); //we get 2
  WriteLn(S, ' - Currency');
  S := FloatToStrF(D, ffNumber, 19, 0); //we get 1
  WriteLn(S, ' - Double');

  WriteLn;
  WriteLn('Using Str procedure:');
  Str(C:19:0, S);
  WriteLn(S, ' - Currency'); //we get 2
  Str(D:19:0, S);
  WriteLn(S, ' - Double'); //we get 1

  Writeln;
  WriteLn('Using WriteLn directly:');
  WriteLn(C:19:0, ' - Currency'); //we get 2
  WriteLn(D:19:0, ' - Double'); //we get 1

  Readln;
end.

(0050638)
Flávio Etrusco (mantis doesn't notify me) (reporter)
2011-08-09 13:08

Note: this bug is reported in the wrong project (Mantis support).
(0058649)
Vincent Snijders (manager)
2012-04-16 13:14

I just noticed this issue. I will move it to the FPC project.
(0058653)
Marco van de Voort (manager)
2012-04-16 18:37

Confirmed for 2.7.1 FreeBSD/x86_64
(0059316)
Max Nazhalov (reporter)
2012-05-06 17:35
edited on: 2012-05-06 19:16

It seems that the problem tracks down to ".\rtl\inc\sstrings.inc::fpc_shortstr_currency()" routine.

This routine always starts rounding from the least significant fractional digit towards the required one propagating the carry for every digit in the way, i.e. rounding "1.4445" to integer results in sequential steps of "1.4445"->"1.445"->"1.45"->"1.5"->"2".

Precisely, this block in ".\rtl\inc\sstrings.inc::fpc_shortstr_currency()" should be completely reviewed:
  { rounding string if r > 0 }
  if r > 0 then
    begin
      ...
    end;

Additional test is attached as CurrencyFormatTest.pp. This one also reveals several formatting glitches with leading zero.

Sample output:

Using Str for 1.444500000000000000E+00
  frac=5, expected=1.44450, got=1.44450
  frac=4, expected=1.4445, got=1.4445
  frac=3, expected=1.445, got=1.445
? frac=2, expected=1.44, got=1.45
? frac=1, expected=1.4, got=1.5
? frac=0, expected=1, got=2

Using Str for 1.999500000000000000E+00
  frac=5, expected=1.99950, got=1.99950
  frac=4, expected=1.9995, got=1.9995
  frac=3, expected=2.000, got=2.000
? frac=2, expected=2.00, got=02.00
? frac=1, expected=2.0, got=02.0
  frac=0, expected=2, got=2

Using Str for -1.999500000000000000E+00
  frac=5, expected=-1.99950, got=-1.99950
  frac=4, expected=-1.9995, got=-1.9995
  frac=3, expected=-2.000, got=-2.000
  frac=2, expected=-2.00, got=-2.00
? frac=1, expected=-2.0, got=-02.0
  frac=0, expected=-2, got=-2

Using Str for 1.994445000000000000E+02
  frac=5, expected=199.44450, got=199.44450
  frac=4, expected=199.4445, got=199.4445
  frac=3, expected=199.445, got=199.445
? frac=2, expected=199.44, got=199.45
? frac=1, expected=199.4, got=199.5
? frac=0, expected=199, got=0200

Using Str for -1.994445000000000000E+02
  frac=5, expected=-199.44450, got=-199.44450
  frac=4, expected=-199.4445, got=-199.4445
  frac=3, expected=-199.445, got=-199.445
? frac=2, expected=-199.44, got=-199.45
? frac=1, expected=-199.4, got=-199.5
? frac=0, expected=-199, got=-0200

(0059344)
Max Nazhalov (reporter)
2012-05-07 10:17

Attached a patch that seems to resolve the problem.

"currency2str_formatting.patch" fixes formatting glitches;
"currency2str_rounding.patch" fixes incorrect rounding.

"CurrencyFormatTest2.pp" was updated to include some more potentially weird test cases.

r21245 testsuit executed with no regression.
(0059350)
Max Nazhalov (reporter)
2012-05-07 14:39
edited on: 2012-05-08 07:07

"currency2str_formatting.patch" should be replaced with "currency2str_formatting_v2.patch".

Now all rounding combinations [str(c:0:0)..str(c:0:4)] formatted exactly like in Delphi.

Directly tested for all numbers from -9999.9999 to 9999.9999.

(0059406)
Max Nazhalov (reporter)
2012-05-08 16:36
edited on: 2012-05-08 17:59

"CurrencyFormatTest3.pp": added a couple of numbers which are represented completely wrong with the unpatched trunk due to formatting bug.

var c:currency;
c:=-99.9997; writeln(c:0:3); -> "-00.000"
c:=-999.9996; writeln(c:0:3); -> "-000.000"

(0059427)
Thaddy de Koning (reporter)
2012-05-09 13:14

Doesn't that break bankers rounding, which is *required* for currency?
I will test this extremely well, because currency is definitly not float for rounding. And I need this not to break.
(0059437)
Max Nazhalov (reporter)
2012-05-09 15:05
edited on: 2012-05-09 15:39

Could You clarify how following numbers should be printed as "currency with 2 digits after dot"?
1.9849
1.9850
1.9851
1.9949
1.9950
1.9951

Delphi 5, Delphi 7 and Delphi XE print them as
1.98
1.99
1.99
1.99
2.00
2.00

If I understand correctly, following the "bankers' rounding" (or "round half to even") this should be
1.98
1.98
1.99
1.99
2.00
2.00

But neither Delphi, nor FPC never print like this, so there is nothing to break here. (However, it is not hard to implement such a feature)

PS. FPC r21245 prints this as
1.99
1.99
1.99
02.00
02.00
02.00


- Issue History
Date Modified Username Field Change
2011-02-07 10:29 Nukool C. New Issue
2011-02-07 13:48 Zoran Vučenović Note Added: 0045869
2011-02-07 13:51 Zoran Vučenović Note Edited: 0045869
2011-08-09 13:08 Flávio Etrusco (mantis doesn't notify me) Note Added: 0050638
2012-04-16 13:14 Vincent Snijders Note Added: 0058649
2012-04-16 13:14 Vincent Snijders Project Mantis => FPC
2012-04-16 14:37 Jonas Maebe FPCOldBugId => 0
2012-04-16 14:37 Jonas Maebe Category => RTL
2012-04-16 18:37 Marco van de Voort Note Added: 0058653
2012-04-16 18:37 Marco van de Voort Status new => confirmed
2012-05-06 17:35 Max Nazhalov File Added: CurrencyFormatTest.pp
2012-05-06 17:35 Max Nazhalov Note Added: 0059316
2012-05-06 19:16 Max Nazhalov Note Edited: 0059316
2012-05-07 10:16 Max Nazhalov File Added: CurrencyFormatTest2.pp
2012-05-07 10:16 Max Nazhalov File Added: currency2str_formatting.patch
2012-05-07 10:17 Max Nazhalov File Added: currency2str_rounding.patch
2012-05-07 10:17 Max Nazhalov Note Added: 0059344
2012-05-07 14:39 Max Nazhalov Note Added: 0059350
2012-05-07 16:31 Max Nazhalov Note Edited: 0059350
2012-05-08 07:07 Max Nazhalov Note Edited: 0059350
2012-05-08 07:07 Max Nazhalov File Added: currency2str_formatting_v2.patch
2012-05-08 16:36 Max Nazhalov File Added: CurrencyFormatTest3.pp
2012-05-08 16:36 Max Nazhalov Note Added: 0059406
2012-05-08 16:38 Max Nazhalov Note Edited: 0059406
2012-05-08 17:59 Max Nazhalov Note Edited: 0059406
2012-05-09 13:14 Thaddy de Koning Note Added: 0059427
2012-05-09 15:05 Max Nazhalov Note Added: 0059437
2012-05-09 15:11 Max Nazhalov Note Edited: 0059437
2012-05-09 15:32 Max Nazhalov Note Edited: 0059437
2012-05-09 15:39 Max Nazhalov Note Edited: 0059437
2012-05-18 16:14 Florian Relationship added related to 0022063
2012-05-19 16:55 Florian Fixed in Revision => 21339
2012-05-19 16:55 Florian Status confirmed => resolved
2012-05-19 16:55 Florian Fixed in Version => 2.7.1
2012-05-19 16:55 Florian Resolution open => fixed
2012-05-19 16:55 Florian Assigned To => Florian
2012-06-01 14:11 Max Nazhalov Tag Attached: currency



MantisBT 1.2.12[^]
Copyright © 2000 - 2012 MantisBT Group
Powered by Mantis Bugtracker