converting float to double

Discussion in 'C Programming' started by Dilip, Dec 19, 2006.

  1. Dilip

    Dilip Guest

    Recently in our code, I ran into a situation where were stuffing a
    float inside a double. The precision was extended automatically
    because of that. To make a long story short, this caused problems
    elsewhere in another part of the system where that figure was used for
    some calculation and some eventual truncation led to the system going
    haywire. So my question is, given this code:

    int main()
    {
    float f = 59.89F;
    /* the following line caused problems */
    double d = f;

    /* they ended up solving it like this */
    f *= 1000.0;
    double dd = (double)f / 1000.0;

    return 0;
    }

    I see what is being done but why does the latter make the situation
    better?
    (consider 'f' in real life to hold stock prices)
     
    Dilip, Dec 19, 2006
    #1
    1. Advertising

  2. Dilip

    Guest

    Dilip wrote:
    > Recently in our code, I ran into a situation where were stuffing a
    > float inside a double. The precision was extended automatically
    > because of that. To make a long story short, this caused problems
    > elsewhere in another part of the system where that figure was used for
    > some calculation and some eventual truncation led to the system going
    > haywire. So my question is, given this code:
    >
    > int main()
    > {
    > float f = 59.89F;
    > /* the following line caused problems */
    > double d = f;
    >
    > /* they ended up solving it like this */
    > f *= 1000.0;
    > double dd = (double)f / 1000.0;
    >
    > return 0;
    > }
    >
    > I see what is being done but why does the latter make the situation
    > better?
    > (consider 'f' in real life to hold stock prices)


    Not a good idea...

    Floating point is by its nature imprecise - multiplying by 1000 simply
    adjusts the imprecision in a way which was helpful in this specific
    case, but may not be helpful in all cases (AFAIK).

    If you want to safely and accurately handle this sort of data, sources
    such as http://www2.hursley.ibm.com/decimal/ may be helpful.
     
    , Dec 19, 2006
    #2
    1. Advertising

  3. Dilip

    CBFalconer Guest

    Dilip wrote:
    >
    > Recently in our code, I ran into a situation where were stuffing a
    > float inside a double. The precision was extended automatically
    > because of that. To make a long story short, this caused problems
    > elsewhere in another part of the system where that figure was used
    > for some calculation and some eventual truncation led to the system
    > going haywire. So my question is, given this code:
    >
    > int main()
    > {
    > float f = 59.89F;
    > /* the following line caused problems */
    > double d = f;
    >
    > /* they ended up solving it like this */
    > f *= 1000.0;
    > double dd = (double)f / 1000.0;
    >
    > return 0;
    > }
    >
    > I see what is being done but why does the latter make the
    > situation better?
    > (consider 'f' in real life to hold stock prices)


    It doesn't. It should make it dead wrong. Either you are not
    showing the real situation or you have a compiler bug.

    Alternatively, if you are depending on exact values from floats
    and/or doubles, your code is broken. Since stock prices (today)
    are decimalized, just use a normalized integer of suitable size.
    Read Knuth (TAOCP) on floating point and expected errors.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
     
    CBFalconer, Dec 19, 2006
    #3
  4. Dilip

    pete Guest

    Dilip wrote:
    >
    > Recently in our code, I ran into a situation where were stuffing a
    > float inside a double. The precision was extended automatically
    > because of that. To make a long story short, this caused problems
    > elsewhere in another part of the system where that figure was used for
    > some calculation and some eventual truncation led to the system going
    > haywire. So my question is, given this code:
    >
    > int main()
    > {
    > float f = 59.89F;
    > /* the following line caused problems */
    > double d = f;
    >
    > /* they ended up solving it like this */
    > f *= 1000.0;
    > double dd = (double)f / 1000.0;
    >
    > return 0;
    > }
    >
    > I see what is being done but why does the latter make the situation
    > better?
    > (consider 'f' in real life to hold stock prices)


    I wouldn't have used a float variable like that to begin with.

    Use float,
    when you need the smallest floating point type.

    Use long double,
    when you need the floating point type
    with most precision and or range.

    Use double,
    all the rest of the time.

    --
    pete
     
    pete, Dec 19, 2006
    #4
  5. Dilip

    Dilip Guest

    CBFalconer wrote:
    > Dilip wrote:
    > >
    > > Recently in our code, I ran into a situation where were stuffing a
    > > float inside a double. The precision was extended automatically
    > > because of that. To make a long story short, this caused problems
    > > elsewhere in another part of the system where that figure was used
    > > for some calculation and some eventual truncation led to the system
    > > going haywire. So my question is, given this code:
    > >
    > > int main()
    > > {
    > > float f = 59.89F;
    > > /* the following line caused problems */
    > > double d = f;
    > >
    > > /* they ended up solving it like this */
    > > f *= 1000.0;
    > > double dd = (double)f / 1000.0;
    > >
    > > return 0;
    > > }
    > >
    > > I see what is being done but why does the latter make the
    > > situation better?
    > > (consider 'f' in real life to hold stock prices)

    >
    > It doesn't. It should make it dead wrong. Either you are not
    > showing the real situation or you have a compiler bug.


    I am showing exactly what is being done in our codebase. Why do you
    say there is a compiler bug? If you try the example, as soon as the
    1st line is executed the variable f contains 59.889999. After its
    stuffed into double d, it becomes 59.889999389648437 (I know these
    values vary after a certain decimal position). The
    multiplication/division to 1000.0 however produces 59.890000000000001
    in dd. The management somehow feels thats a more "accurate"
    representation. I guess after rounding off to 2 decimal places they
    expected 59.89 but a bug somewhere in the code ensured that the former
    case got rounded off to 59.88. It was off by a penny and that
    triggered major problems in other calculations.

    > Since stock prices (today)
    > are decimalized, just use a normalized integer of suitable size.
    > Read Knuth (TAOCP) on floating point and expected errors.


    I am not exactly unfamiliar with floating point representations and its
    associated accuracy related problems but I think this is the first time
    I am working in a domain where such problems crop up on a more frequent
    basis. Could you please elaborate on that "normalized integer of
    suitable size"?
     
    Dilip, Dec 19, 2006
    #5
  6. CBFalconer <> writes:
    > Dilip wrote:
    >> Recently in our code, I ran into a situation where were stuffing a
    >> float inside a double. The precision was extended automatically
    >> because of that. To make a long story short, this caused problems
    >> elsewhere in another part of the system where that figure was used
    >> for some calculation and some eventual truncation led to the system
    >> going haywire. So my question is, given this code:
    >>
    >> int main()
    >> {
    >> float f = 59.89F;
    >> /* the following line caused problems */
    >> double d = f;
    >>
    >> /* they ended up solving it like this */
    >> f *= 1000.0;
    >> double dd = (double)f / 1000.0;
    >>
    >> return 0;
    >> }
    >>
    >> I see what is being done but why does the latter make the
    >> situation better?
    >> (consider 'f' in real life to hold stock prices)

    >
    > It doesn't. It should make it dead wrong. Either you are not
    > showing the real situation or you have a compiler bug.


    Are you sure about that? The code multiplies f by 1000.0, then
    divides the result by 1000.0. The *mathematical* result is the same,
    but the way it's done is likely to change the rounding behavior
    slightly. It's not likely to be a general solution to any problem.
    It smacks of "cargo cult programming"; see
    <http://www.catb.org/~esr/jargon/html/C/cargo-cult-programming.html>.

    > Alternatively, if you are depending on exact values from floats
    > and/or doubles, your code is broken. Since stock prices (today)
    > are decimalized, just use a normalized integer of suitable size.
    > Read Knuth (TAOCP) on floating point and expected errors.


    Another good resource is Goldberg's paper "What Every Computer
    Scientist Should Know About Floating-Point". Google "goldberg
    floating" to find it.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 19, 2006
    #6
  7. pete wrote:
    > Dilip wrote:
    > >
    > > Recently in our code, I ran into a situation where were stuffing a
    > > float inside a double. The precision was extended automatically
    > > because of that. To make a long story short, this caused problems
    > > elsewhere in another part of the system where that figure was used for
    > > some calculation and some eventual truncation led to the system going
    > > haywire. So my question is, given this code:
    > >
    > > int main()
    > > {
    > > float f = 59.89F;
    > > /* the following line caused problems */
    > > double d = f;
    > >
    > > /* they ended up solving it like this */
    > > f *= 1000.0;
    > > double dd = (double)f / 1000.0;
    > >
    > > return 0;
    > > }
    > >
    > > I see what is being done but why does the latter make the situation
    > > better?
    > > (consider 'f' in real life to hold stock prices)

    >
    > I wouldn't have used a float variable like that to begin with.
    >
    > Use float,
    > when you need the smallest floating point type.
    >
    > Use long double,
    > when you need the floating point type
    > with most precision and or range.
    >
    > Use double,
    > all the rest of the time.
    >


    This comes squarely under the heading "If you can understand this
    advice you don't need it".

    - William Hughes
    > --
    > pete
     
    William Hughes, Dec 19, 2006
    #7
  8. Dilip

    Random832 Guest

    2006-12-19 <>,
    pete wrote:
    > Dilip wrote:
    >>
    >> Recently in our code, I ran into a situation where were stuffing a
    >> float inside a double. The precision was extended automatically
    >> because of that. To make a long story short, this caused problems
    >> elsewhere in another part of the system where that figure was used for
    >> some calculation and some eventual truncation led to the system going
    >> haywire. So my question is, given this code:
    >>
    >> int main()
    >> {
    >> float f = 59.89F;
    >> /* the following line caused problems */
    >> double d = f;
    >>
    >> /* they ended up solving it like this */
    >> f *= 1000.0;
    >> double dd = (double)f / 1000.0;
    >>
    >> return 0;
    >> }
    >>
    >> I see what is being done but why does the latter make the situation
    >> better?
    >> (consider 'f' in real life to hold stock prices)

    >
    > I wouldn't have used a float variable like that to begin with.
    >
    > Use float,
    > when you need the smallest floating point type.
    >
    > Use long double,
    > when you need the floating point type
    > with most precision and or range.


    Use integers,
    when you need to be exact to within a known specific unit, such as
    a dollar, cent, or Nth part of either.

    > Use double,
    > all the rest of the time.
     
    Random832, Dec 19, 2006
    #8
  9. Dilip

    Random832 Guest

    2006-12-19 <>,
    Dilip wrote:
    > I am not exactly unfamiliar with floating point representations and its
    > associated accuracy related problems but I think this is the first time
    > I am working in a domain where such problems crop up on a more frequent
    > basis. Could you please elaborate on that "normalized integer of
    > suitable size"?


    Have an integer variable [probably type long or long long] counting the
    number of cents (or thousandths of a dollar, or whatever). Doing your
    weird cast thing fixed the error in that one particular case, but could
    have introduced other errors elsewhere.
     
    Random832, Dec 19, 2006
    #9
  10. Dilip

    Dilip Guest

    Keith Thompson wrote:
    > CBFalconer <> writes:
    > > Dilip wrote:
    > >> Recently in our code, I ran into a situation where were stuffing a
    > >> float inside a double. The precision was extended automatically
    > >> because of that. To make a long story short, this caused problems
    > >> elsewhere in another part of the system where that figure was used
    > >> for some calculation and some eventual truncation led to the system
    > >> going haywire. So my question is, given this code:
    > >>
    > >> int main()
    > >> {
    > >> float f = 59.89F;
    > >> /* the following line caused problems */
    > >> double d = f;
    > >>
    > >> /* they ended up solving it like this */
    > >> f *= 1000.0;
    > >> double dd = (double)f / 1000.0;
    > >>
    > >> return 0;
    > >> }
    > >>
    > >> I see what is being done but why does the latter make the
    > >> situation better?
    > >> (consider 'f' in real life to hold stock prices)

    > >
    > > It doesn't. It should make it dead wrong. Either you are not
    > > showing the real situation or you have a compiler bug.

    >
    > Are you sure about that? The code multiplies f by 1000.0, then
    > divides the result by 1000.0. The *mathematical* result is the same,
    > but the way it's done is likely to change the rounding behavior
    > slightly. It's not likely to be a general solution to any problem.
    > It smacks of "cargo cult programming"; see
    > <http://www.catb.org/~esr/jargon/html/C/cargo-cult-programming.html>.


    I totally agree which is the reason why I posted to this NG to
    understand what exactly is being solved by that 1000.0 workaround.

    > Another good resource is Goldberg's paper "What Every Computer
    > Scientist Should Know About Floating-Point". Google "goldberg
    > floating" to find it.


    I came across that paper quite a few times in the past. I never
    realized one day I would need to know that amount of detail. Do you
    have any insights into that normalized integer thing everyone has been
    pointing out so far? If one of you can give me an example, i'd
    appreciate it.
     
    Dilip, Dec 19, 2006
    #10
  11. Dilip

    Guest

    Dilip wrote:
    > I came across that paper quite a few times in the past. I never
    > realized one day I would need to know that amount of detail. Do you
    > have any insights into that normalized integer thing everyone has been
    > pointing out so far? If one of you can give me an example, i'd
    > appreciate it.


    Store the amount as pennies in a long long integer. The Goldberg paper
    is a must read if you are doing numerics with other people's money.
    IMO-YMMV.

    #include <stdio.h>
    #include <stdlib.h>

    char string[256];
    int main(void)
    {
    long long pennies;

    try_again:
    puts("Enter a cost in pennies:");
    if (fgets(string, sizeof string, stdin)) {
    sscanf(string, "%lld", &pennies);
    printf("That's %lld dollars and %lld cents or $%lld.%lld\n",
    pennies / 100, pennies % 100, pennies / 100, pennies % 100);
    } else
    goto try_again;

    return EXIT_SUCCESS;
    }
    /* e.g.:
    Enter a cost in pennies:
    99999999
    That's 999999 dollars and 99 cents or $999999.99
    */
     
    , Dec 19, 2006
    #11
  12. Dilip

    Malcolm Guest

    "Dilip" <> wrote in message
    news:...
    >
    > Recently in our code, I ran into a situation where were stuffing a
    > float inside a double. The precision was extended automatically
    > because of that. To make a long story short, this caused problems
    > elsewhere in another part of the system where that figure was used for
    > some calculation and some eventual truncation led to the system going
    > haywire. So my question is, given this code:
    >
    > int main()
    > {
    > float f = 59.89F;
    > /* the following line caused problems */
    > double d = f;
    >
    > /* they ended up solving it like this */
    > f *= 1000.0;
    > double dd = (double)f / 1000.0;
    >
    > return 0;
    > }
    >
    > I see what is being done but why does the latter make the situation
    > better?
    > (consider 'f' in real life to hold stock prices)
    >

    That is called hacking.
    Somehow a cent must have been knocked off in the code - decimals cannot be
    represented perfectly in binary floating point notation - leading the
    program to suspect salami tactics. Multiplying by 1000 converts the number
    to an integer, and the division is done in double precision, so the cent
    might not have been dropped.

    This approach to problem solving, incidentally, is known as hacking, and is
    an indication that the company's management is in a serious mess.
    --
    www.personal.leeds.ac.uk/~bgy1mm
    freeware games to download.
     
    Malcolm, Dec 19, 2006
    #12
  13. Dilip

    CBFalconer Guest

    Dilip wrote:
    > Keith Thompson wrote:
    >> CBFalconer <> writes:
    >>> Dilip wrote:
    >>>
    >>>> Recently in our code, I ran into a situation where were stuffing a
    >>>> float inside a double. The precision was extended automatically
    >>>> because of that. To make a long story short, this caused problems
    >>>> elsewhere in another part of the system where that figure was used
    >>>> for some calculation and some eventual truncation led to the system
    >>>> going haywire. So my question is, given this code:
    >>>>
    >>>> int main()
    >>>> {
    >>>> float f = 59.89F;
    >>>> /* the following line caused problems */
    >>>> double d = f;
    >>>>
    >>>> /* they ended up solving it like this */
    >>>> f *= 1000.0;
    >>>> double dd = (double)f / 1000.0;
    >>>>
    >>>> return 0;
    >>>> }
    >>>>
    >>>> I see what is being done but why does the latter make the
    >>>> situation better?
    >>>> (consider 'f' in real life to hold stock prices)
    >>>
    >>> It doesn't. It should make it dead wrong. Either you are not
    >>> showing the real situation or you have a compiler bug.

    >>
    >> Are you sure about that? The code multiplies f by 1000.0, then
    >> divides the result by 1000.0. The *mathematical* result is the same,
    >> but the way it's done is likely to change the rounding behavior
    >> slightly. It's not likely to be a general solution to any problem.
    >> It smacks of "cargo cult programming"; see
    >> <http://www.catb.org/~esr/jargon/html/C/cargo-cult-programming.html>.

    >
    > I totally agree which is the reason why I posted to this NG to
    > understand what exactly is being solved by that 1000.0 workaround.
    >
    >> Another good resource is Goldberg's paper "What Every Computer
    >> Scientist Should Know About Floating-Point". Google "goldberg
    >> floating" to find it.

    >
    > I came across that paper quite a few times in the past. I never
    > realized one day I would need to know that amount of detail. Do you
    > have any insights into that normalized integer thing everyone has been
    > pointing out so far? If one of you can give me an example, i'd
    > appreciate it.


    As a temporary measure, try converting the value to a long:

    long longvalueincents;

    longvalueincents = (f * 100) + 0.5; /* control rounding */

    and, to print it out, try:

    printf("%ld.%ld", longvalueincents/100, longvalueincents%100);
    fflush(stdout);

    Note that you don't need any casts. A cast is probably an error.

    You can probably incorporate all this in a single function that
    dumps the double rounded to two decimals, but reading the printf
    documentation is likely to be more rewarding.

    You could also hire me. :) See below.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
     
    CBFalconer, Dec 19, 2006
    #13
  14. Dilip

    Malcolm Guest

    <> wrote in message
    news:...
    > Dilip wrote:
    >> I came across that paper quite a few times in the past. I never
    >> realized one day I would need to know that amount of detail. Do you
    >> have any insights into that normalized integer thing everyone has been
    >> pointing out so far? If one of you can give me an example, i'd
    >> appreciate it.

    >
    > Store the amount as pennies in a long long integer. The Goldberg paper
    > is a must read if you are doing numerics with other people's money.
    > IMO-YMMV.
    >

    Or in a double, but as an integral number of pence.
    That way the maths is accurate up to 48 bits or so, and degrades garcefully
    under hyperinflation.
    --
    www.personal.leeds.ac.uk/~bgy1mm
    freeware games to download.
     
    Malcolm, Dec 20, 2006
    #14
  15. Dilip wrote:
    > Recently in our code, I ran into a situation where were stuffing a
    > float inside a double. The precision was extended automatically
    > because of that. To make a long story short, this caused problems
    > elsewhere in another part of the system where that figure was used for
    > some calculation and some eventual truncation led to the system going
    > haywire. So my question is, given this code:
    >
    > int main()
    > {
    > float f = 59.89F;
    > /* the following line caused problems */
    > double d = f;
    >
    > /* they ended up solving it like this */
    > f *= 1000.0;
    > double dd = (double)f / 1000.0;
    >
    > return 0;
    > }
    >
    > I see what is being done but why does the latter make the situation
    > better?
    > (consider 'f' in real life to hold stock prices)


    For the purposes of this explanation treat double as exact
    and float as approximate.

    The problem is that most exact decimal fractions cannot
    be represented exactly by floats. So you need to use
    a value that is just a little above or just a little below.

    Suppose we have

    f=0.0001

    then f will have a value slightly below 0.0001
    (or maybe not, but it did on my machine just now).

    Now multiply by 1000
    Now f will have to approximate 0.1. The best approximation is
    a value slightly above 0.1 (at least on my machine just now)
    So after

    1000*f

    we get a value slightly above 0.1. We now assign to a double

    dd=1000*f

    (This is done by first calculating 1000*f as a float and then
    assigning to double). We next divide dd by 1000.
    dd now has a value slightly greater than 0.0001.

    So the net effect of multiplying by 1000, storing in a double, then
    dividing by 1000, is to convert a value slightly below 0.0001 to a
    value
    slightly above 0.0001. Because the code is clearly incompetently
    written, it will later blindly truncate, converting a miniscule
    difference into
    a noticable one.

    Of course if you start out with some other value for f, something
    different
    may happen. Something different may happen on different machines,
    or with different compilers, or with different compiler options, or on
    different days, or on different runs, or at different times within the
    same run.

    I wouldn't trust this code in a rigged demo.

    - William Hughes.
     
    William Hughes, Dec 20, 2006
    #15
  16. In article <> "Dilip" <> writes:
    > Recently in our code, I ran into a situation where were stuffing a
    > float inside a double. The precision was extended automatically
    > because of that. To make a long story short, this caused problems
    > elsewhere in another part of the system where that figure was used for
    > some calculation and some eventual truncation led to the system going
    > haywire. So my question is, given this code:

    ....
    > float f = 59.89F;
    > /* the following line caused problems */
    > double d = f;


    d will be approximately equal to 59.89 with the same precision as f

    > /* they ended up solving it like this */
    > f *= 1000.0;


    By sheer luck (due to the rounding rules) f is exactly equal to 59890.
    (You could even use 100 here with exactly the same results.)

    > double dd = (double)f / 1000.0;


    And so this is a better approximation in double precision of 59.89.

    > I see what is being done but why does the latter make the situation
    > better?


    It is only luck. For other values of f it could fail and dd could
    (I think) even be worse than d.

    > (consider 'f' in real life to hold stock prices)


    Consider not to use floating point for stock prices. Floating point
    inherently carries imprecision (especially if you want to do decimal
    calculations), which you do not want with stock prices.
    --
    dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
    home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
     
    Dik T. Winter, Dec 20, 2006
    #16
  17. In article <> "Dilip" <> writes:
    ....
    > I am showing exactly what is being done in our codebase. Why do you
    > say there is a compiler bug?


    There is indeed none, but you are misunderstanding floating point.

    > If you try the example, as soon as the
    > 1st line is executed the variable f contains 59.889999. After its
    > stuffed into double d, it becomes 59.889999389648437 (I know these
    > values vary after a certain decimal position).


    They do not vary, but you should print with sufficient precision.
    The exact value stored in both f and d is:
    59.8899993896484375

    > The
    > multiplication/division to 1000.0 however produces 59.890000000000001
    > in dd.


    Actually the value stored in dd is:
    59.8900000000000005684341886080801486968994140625
    But as I stated in another article, it is only luck that this value is
    larger than 59.89.

    > The management somehow feels thats a more "accurate"
    > representation. I guess after rounding off to 2 decimal places they
    > expected 59.89 but a bug somewhere in the code ensured that the former
    > case got rounded off to 59.88.


    Probably not rounding was done but truncation. In that case
    when d * 100 is truncated to int it will indeed give 59.88 and
    dd * 100 is truncated to 59.89. I can come up with initial values
    where this is all reversed. And it is even platform dependent.
    See message <>
    in comp.arch.arithmetic and the associated thread.

    > It was off by a penny and that
    > triggered major problems in other calculations.


    If off by a penny triggers major problems, you should *really* consider
    using integer arithmetic in pennies.

    > > Since stock prices (today)
    > > are decimalized, just use a normalized integer of suitable size.
    > > Read Knuth (TAOCP) on floating point and expected errors.

    >
    > I am not exactly unfamiliar with floating point representations and its
    > associated accuracy related problems but I think this is the first time
    > I am working in a domain where such problems crop up on a more frequent
    > basis. Could you please elaborate on that "normalized integer of
    > suitable size"?


    Use 64 bit integers for the amounts in pennies. When you use floating
    point and store the amount in dollars you should not be surprised that
    after a number of calculations the result is off by a penny (or perhaps
    more). Floating point variables can not store amounts in dollars with
    precision upto pennies.
    --
    dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
    home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
     
    Dik T. Winter, Dec 20, 2006
    #17
  18. Dilip

    Thad Smith Guest

    wrote:

    > printf("That's %lld dollars and %lld cents or $%lld.%lld\n",
    > pennies / 100, pennies % 100, pennies / 100, pennies % 100);


    printf("That's %lld dollars and %lld cents or $%lld.%02lld\n",
    pennies / 100, pennies % 100, pennies / 100, pennies % 100);


    --
    Thad
     
    Thad Smith, Dec 20, 2006
    #18
  19. "Malcolm" <> writes:
    > <> wrote in message
    > news:...
    >> Dilip wrote:
    >>> I came across that paper quite a few times in the past. I never
    >>> realized one day I would need to know that amount of detail. Do you
    >>> have any insights into that normalized integer thing everyone has been
    >>> pointing out so far? If one of you can give me an example, i'd
    >>> appreciate it.

    >>
    >> Store the amount as pennies in a long long integer. The Goldberg paper
    >> is a must read if you are doing numerics with other people's money.
    >> IMO-YMMV.
    >>

    > Or in a double, but as an integral number of pence.
    > That way the maths is accurate up to 48 bits or so, and degrades garcefully
    > under hyperinflation.


    For certain values of "gracefully".

    In some contexts, I would think that a one-penny error in a
    multi-trillion pound calculation ("trillion" meaning 10**12) would be
    considered unacceptable.

    64-bit integers should be more than enough to handle anything short of
    really extreme hyperinflation with no errors -- assuming that
    addition, subtraction, and multiplication by whole numbers are the
    only required operations.

    Compound interest introduces some interesting problems, but I think
    there are very specific rules for how to do those calculations. I
    suspect floating-point would not implement those rules correctly.

    Warning: I'm musing about stuff I've heard about here and there, but
    in which I have no particular expertise.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 20, 2006
    #19
  20. "Dik T. Winter" <> writes:
    [...]
    > Consider not to use floating point for stock prices. Floating point
    > inherently carries imprecision (especially if you want to do decimal
    > calculations), which you do not want with stock prices.


    If you need to do calculations with stock prices, find out what the
    formal rules are for doing those calculations. (I have no idea what
    those rules are, or where you'd find out about them.) Once you've
    done that, implement those rules. ("How?" "Correctly.")

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 20, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sydex
    Replies:
    12
    Views:
    6,505
    Victor Bazarov
    Feb 17, 2005
  2. bd
    Replies:
    0
    Views:
    634
  3. mathieu
    Replies:
    9
    Views:
    742
    James Kanze
    Sep 15, 2007
  4. Carsten Fuchs
    Replies:
    45
    Views:
    1,554
    James Kanze
    Oct 8, 2009
  5. Dipesh Batheja
    Replies:
    1
    Views:
    576
    Bernard Kenik
    Nov 16, 2006
Loading...

Share This Page