Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

Major floating point error problem

edited February 2005 in General
Hi,

Got a real problem here that I just can't find a workaround for.
Here's the simplest way to reproduce it:

Create a table in MS Access with two fields, one a Double and one a
Currency type. Add a single row to the table with the value 2.175 in
each field.

Now if I add this table and the two field definitions to my data
dictionary and then create a brand new report which does nothing other
than place the two values in the detail band, but formatted as
currency fields and thus rounded to two decimal places, then both
fields display as £2.17 rather than the correct value of £2.18

As you're no doubt aware, not all decimal values can be stored exactly
in a floating point field due to it's binary nature. Indeed if you
pull the aforementioned row into a simple TADOTable or similar then
you'll see that the value of the TFloatField produced for the Double
value isn't actually 2.175 but very fractionally below this value.
The inspector appears to show the value as 2.175 but if you subtract
2.175 from it you'll see there's an error at around the 16th decimal
place. Rounding this value to two decimal places thus produces 2.17,
which seems to be the same phenomenon as is happening in the report.

Currency fields in Access produce TBCDFields when pulled into a delphi
TADOTable or similar, and get around this floating point error problem
and round correctly, yet RB still seems to treat such Currency fields
as floating point values and produce the same errors.

Can anyone shed any light on exactly what's going on here or what I
can do to correct this problem. As the figures involved are currency
ones, you can imagine that they need to be right and there's a world
of difference between 2.17 and 2.18.

Pertinent system info:

RB 7.03 Enterprise
D6 Pro
W2K SP4

Many thanks,
--
Toby

Comments

  • edited February 2005
    Hi Toby,

    This issue was addressed for the latest version of ReportBuilder. Please
    upgrade to RB 9.01.

    --
    Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited February 2005
    On Fri, 4 Feb 2005 08:45:04 -0700, "Nico Cizik \(Digital Metaphors\)"
  • edited February 2005
    On Fri, 4 Feb 2005 08:45:04 -0700, "Nico Cizik \(Digital Metaphors\)"
  • edited February 2005
    Hi Toby,

    I'm sorry, I misread your first post. We did make a few fixes to the
    DisplayFormat class having to do with the formatting of currency values that
    are still of value to you. The article below describes how the class works
    and how you can customize it to give you the output you want.

    ---------------------------------------------
    Article: Currency Formatting in ReportBuilder
    ---------------------------------------------

    Currently when formatting currency display formats, ReportBuilder internally
    calls FloatToStrF with a ffCurrency paramter.

    This honors the Windows currency settings.

    There are two ways to override this behavior:


    1. Create a descendant of TppDisplayFormat.

    See ppDisplayFormat.pas. YOu can easily create a descendant of
    TppDisplayFormat and specify that your TmyDisplayFormat be used by
    ReportBuilder to perform formatting. See the initialization section
    ppDisplayFormat.pas.




    2. Override the Window currency values

    You can override this by setting Delphi's global variables for
    DecimalSeparator and CurrencyString. You will probably want to restore these
    values after printing the report.

    Below is a simple example:

    var
    lcSaveDecimalSeparator: Char;
    lsCurrencyString: String;

    begin

    lcSaveDecimalSeparator := DecimalSeparator;
    lsCurrencyString := CurrencyString;

    DecimalSeparator := '.';
    CurrencyString := '$';

    try
    Report.Print;
    finally

    DecimalSeparator := lcSaveDecimalSeparator;
    CurrencyString := lsCurrencyString;
    end;


    end;



    For the end-user solution you may to code an event-handler
    for the Report.Template.OnLoadEnd event to setup the proper settings.


    --
    Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
This discussion has been closed.