converting float to double

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • William Hughes

    #46
    Re: converting float to double


    dcorbit@connx.c om wrote:
    William Hughes wrote:
    Dik T. Winter wrote:
    In article <1166646566.617 718.113730@i12g 2000cwa.googleg roups.com"Willi am Hughes" <wpihughes@hotm ail.comwrites:
    Dilip wrote:
    ...
    THis isn't always possible. The market data vendor I connect to
    insists that I read the stock prices as float. So when I reach into
    the byte-stream I will have to memcpy sizeof(float) number of bytes.
    Since everywhere else the system uses double to hold these prices, I
    had no choice but to stuff that retreived float value into a double
    causing all these problems.
    >
    A system that uses floating point variables to store prices should
    work correctly if a price is just above or just below the
    correct price (e.g for a price of 0.010001 dollars or 0.009998
    dollars).
    The system you use does not have this property. It needs
    to be fixed.
    >
    How do you fix a system that follows the C standard?
    >
    A possible workaround:
    Read the prices as float
    Round to the nearest cent or tenth of a cent (*)
    Convert to double
    Add a fudge factor of 0.00000001
    Now your prices will be subtly wrong, but they will be subtly wrong in
    the correct direction. This should work as well as the
    (double)(f*1000 .0)/1000.0
    kludge, and will work for any value.
    >
    But after subtraction you can be subtly wrong the wrong way.

    Indeed. This is not a fix. This is a kludge that might work with
    a broken system.
    The suggested kludge does not make the errors any worse
    (we expect an error of about 10e-6 times the shareprice)
    It just insures that the errors have a consistent sign. The
    alternative
    of not adding the fudge factor mean that there will still
    be some error with unknown sign. The preferred alternatives
    of avoiding or rewriting the software do not appear to be
    available.
    To avoid
    all this is done by internally working with integers, longs, long longs,
    or whatever integer size you need.
    Just remember you may be dealing with the world GDP expressed
    in Turkish lira. Or design your system to use floating point and be
    tolerant of
    small errors In the end you need to find out what the correct answer
    is (this is an accounting, not a mathematical or computer question)
    and design your system to give the correct answer. What internal
    data type or structure you use to do this is of lesser importance.
    >
    A 64 bit integer will correctly model currency to 18 digits (with
    hundredths units that gives 16 digits for the integer part).
    In a mythical currency with 1,000,000 units per dollar,
    Nothing mythical here.

    1 US dollar = 1374865.7 Turkish Lira
    that would
    leave 10 billion dollar transactions accurate to the penny.
    So don't use 64 bit integers to calculate the world GDP in
    Turkish Lira unless your system is tolerant of small errors.
    >
    With 6 digits {typically} of precision, float can barely handle a
    decent paycheck. Float is one of the most onerous native C data type
    that I can imagine for use with currency.
    Both char and short are (probably) worse.
    Double on the other hand is fine for many uses.
    float has many uses, currency calculations is not among them.

    Our database tools do all
    calcuations in 110 digits of precision (so that things like interest
    calculations for the national debt over 100 years would still yield
    sensible results).
    As pointed out: Find out what the correct answer is, then design
    your system. It may be that no native type is sufficient.

    >
    For instance,
    select convert(8624231 011335.27 * pow(1+(.05/4),100*4), varchar(256))
    returns:
    124088957459618 1.0524862250897 801838715263375 815269734635536 879733900109878 357698345898209 198819494984492 8

    Looks to me like you are using high precision floating point arithmetic
    (rather than arbitrary precision integer arithmetic), then rounding to
    get your final answer. Nothing wrong with this strategy, but it is
    hardly an argument in favour of integer arithmetic.

    - William
    Hughes

    Comment

    • Dik T. Winter

      #47
      Re: converting float to double

      In article <87d56e9kp3.fsf @blp.benpfaff.o rgblp@cs.stanford .edu writes:
      "Dik T. Winter" <Dik.Winter@cwi .nlwrites:
      >
      In article <87r6uu9z60.fsf @blp.benpfaff.o rgblp@cs.stanford .edu writes:
      Random832 <random@random. yi.orgwrites:
      price_cents = round(f*100.);
      For what it's worth, the round function is new in C99.
      For this kind of data, (int)ftrunc(f * 100 + 0.5) works just as well.
      >
      I can't find any mention of ftrunc, in C99 or even in SUSv3.
      Yup. I meant "floor". (That happens when you are using a large
      variety of environments.)
      --
      dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
      home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

      Comment

      • Random832

        #48
        Re: converting float to double

        2006-12-20 <1166657795.070 718.292400@t46g 2000cwa.googleg roups.com>,
        dcorbit@connx.c om wrote:
        >
        CBFalconer wrote:
        >Ben Pfaff wrote:
        Random832 <random@random. yi.orgwrites:
        >
        >Well - if you can't get a better vendor, the best way would be
        >to do this:
        >>
        > #include <math.h>
        > //...
        > float floating_price;
        > long int price_cents;
        > //...
        > price_cents = round(f*100.);
        >
        For what it's worth, the round function is new in C99.
        >>
        >and unnecessary.
        >>
        > price_cents = 100 * floating_price + 0.5;
        >
        Almost:
        >>From the C-FAQ:
        14.6: How do I round numbers?
        >
        A: The simplest and most straightforward way is with code like
        >
        (int)(x + 0.5)
        >
        This technique won't work properly for negative numbers,
        though (for which you could use something like
        (int)(x < 0 ? x - 0.5 : x + 0.5)).
        >
        Also, most banking institutions will prefer banker's rounding to simple
        rounding.
        This is for converting floats that are precise to one cent to ints
        _once_, not how to round stuff for ongoing calculations. I.e, you're not
        trying to figure out which way to round 12.945 in, you're trying to
        figure out whether when the data says 12.949999809265 13671875, if that's
        12.94 or 12.95.

        Comment

        • Random832

          #49
          Re: converting float to double

          2006-12-21 <1166664815.506 171.203210@a3g2 000cwd.googlegr oups.com>,
          dcorbit@connx.c om wrote:
          In a mythical currency with 1,000,000 units per dollar,
          The Turkish Lira is not mythical, though it is obsolete.

          Comment

          • Dik T. Winter

            #50
            Re: converting float to double

            In article <1166661266.013 993.183370@n67g 2000cwd.googleg roups.com"Willi am Hughes" <wpihughes@hotm ail.comwrites:
            Dik T. Winter wrote:
            ....
            But after subtraction you can be subtly wrong the wrong way.
            >
            Indeed. This is not a fix. This is a kludge that might work with
            a broken system.
            What of the system is broken?
            To avoid
            all this is done by internally working with integers, longs, long longs,
            or whatever integer size you need.
            >
            Just remember you may be dealing with the world GDP expressed
            in Turkish lira. Or design your system to use floating point and be
            tolerant of small errors.
            The current Turkish Lira would do pretty well. The previous one would
            be bad, especially if you want to keep up to figures until the nearest
            Kuru. But when somebody complains that there is a difference of one
            cent in the result, that only means that the calculations are done
            using the wrong data type. If you expect that anybody in Turkey before
            the introduction of the new Lira bothered about anything less than
            25000 Lira, you are wrong. (I still remember the 10,000,000 Lira tip
            for the waiter after a small lunch for four.)

            No financial program can cope with hyperinflation when it does not
            regularly adjust to the inputs. You should know the smallest amount
            that legally can be distinguished and base your calculations on that;
            using integers. Picking the Turkish Lira is a red herring. You
            could equally well have picked the Hungarian Pengo from just after
            the war. If I have it right, at some moment they had notes of
            1,000,000,000,0 00,000,000,000, 000 Pengo. Or the Zimbabwian dollar
            notes that have printed on them an ultimate date of validity (which
            is not more than six months after introduction).

            The whole point is that in most financial transactions it is precisely
            defined how fractions of something should be rounded. Any attempt to
            be slightly imprecise (using floating point) will fail at some point
            or another.
            In the end you need to find out what the correct answer
            is (this is an accounting, not a mathematical or computer question)
            and design your system to give the correct answer. What internal
            data type or structure you use to do this is of lesser importance.
            But floating point does not help at all.
            --
            dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
            home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

            Comment

            • Dik T. Winter

              #51
              Re: converting float to double

              In article <1166666262.298 339.130380@73g2 000cwn.googlegr oups.com"Willia m Hughes" <wpihughes@hotm ail.comwrites:
              ....
              A 64 bit integer will correctly model currency to 18 digits (with
              hundredths units that gives 16 digits for the integer part).
              In a mythical currency with 1,000,000 units per dollar,
              >
              Nothing mythical here.
              >
              1 US dollar = 1374865.7 Turkish Lira
              You are out of date. 1 US dollar = 1.4283 Turkish Lira.
              that would
              leave 10 billion dollar transactions accurate to the penny.
              >
              So don't use 64 bit integers to calculate the world GDP in
              Turkish Lira unless your system is tolerant of small errors.
              You still fail to see how the financial world is looking at it.
              They require exactness to some predefined unit. And if some
              system requires precision to the cent, do the calculations to
              the cent.
              --
              dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
              home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

              Comment

              • CBFalconer

                #52
                Re: converting float to double

                Ernie Wright wrote:
                CBFalconer wrote:
                >Ben Pfaff wrote:
                >>
                >>For what it's worth, the round function is new in C99.
                >>
                >and unnecessary.
                >>
                > price_cents = 100 * floating_price + 0.5;
                >
                which is only one of several widely used rounding rules, and not
                necessarily the one preferred for financial transactions.
                which won't matter in the case posted by the OP. He started with a
                constant of the form 89.13, i.e. with exactly 2 decimal places.
                The above will capture the original value.

                --
                Chuck F (cbfalconer at maineline dot net)
                Available for consulting/temporary embedded and systems.
                <http://cbfalconer.home .att.net>

                Comment

                • William Hughes

                  #53
                  Re: converting float to double


                  Dik T. Winter wrote:
                  In article <1166666262.298 339.130380@73g2 000cwn.googlegr oups.com"Willia m Hughes" <wpihughes@hotm ail.comwrites:
                  ...
                  A 64 bit integer will correctly model currency to 18 digits (with
                  hundredths units that gives 16 digits for the integer part).
                  In a mythical currency with 1,000,000 units per dollar,
                  >
                  Nothing mythical here.
                  >
                  1 US dollar = 1374865.7 Turkish Lira
                  >
                  You are out of date. 1 US dollar = 1.4283 Turkish Lira.
                  No 1 US dollar = 1.4283 New Turkish Lira.

                  Yes, the convesion contant came from a table that was
                  a few years old. That hardly makes the Turkish Lira
                  mythical.
                  - William Hughes

                  Comment

                  • CBFalconer

                    #54
                    Re: converting float to double

                    William Hughes wrote:
                    Dik T. Winter wrote:
                    >
                    .... snip ...
                    >>
                    >To avoid all this is done by internally working with integers,
                    >longs, long longs, or whatever integer size you need.
                    >
                    Just remember you may be dealing with the world GDP expressed in
                    Turkish lira. Or design your system to use floating point and be
                    tolerant of small errors In the end you need to find out what
                    the correct answer is (this is an accounting, not a mathematical
                    or computer question) and design your system to give the correct
                    answer. What internal data type or structure you use to do this
                    is of lesser importance.
                    Mumble years ago I was rewriting a payroll program (in Cobol) for a
                    municipality. The original had done all sorts of multiple rounding
                    operations, giving minor erroneous results, and I corrected this as
                    a matter of course. The net result was a penny or two difference
                    in actual paychecks, but summaries were correct and the books
                    balanced.

                    You wouldn't believe the screams from the payees. Obviously they
                    were in the habit of checking things themselves, rounding at every
                    opportunity. Also they obviously didn't trust "the computer" worth
                    a damn. To quiet the insurrection I had to put back the faulty
                    calculations.

                    --
                    Chuck F (cbfalconer at maineline dot net)
                    Available for consulting/temporary embedded and systems.
                    <http://cbfalconer.home .att.net>


                    Comment

                    • Ernie Wright

                      #55
                      Re: converting float to double

                      CBFalconer wrote:
                      Ernie Wright wrote:
                      >CBFalconer wrote:
                      >>Ben Pfaff wrote:
                      >>>
                      >>>For what it's worth, the round function is new in C99.
                      >>>
                      >>and unnecessary.
                      >>>
                      >> price_cents = 100 * floating_price + 0.5;
                      >>
                      >which is only one of several widely used rounding rules, and not
                      >necessarily the one preferred for financial transactions.
                      >
                      which won't matter in the case posted by the OP. He started with a
                      constant of the form 89.13, i.e. with exactly 2 decimal places.
                      I infer that he started with a 32-bit IEEE float, which can only have
                      exactly two decimal places if they happen to be ".25", ".50" or ".75".

                      If he were really starting with a constant in the code, he wouldn't
                      need a rounding formula. He could just erase the decimal point.
                      The above will capture the original value.
                      Which will only help if the OP is planning to rewrite his entire
                      application to use integers instead of doubles, an option he appears not
                      to be entertaining.

                      The problem described by the OP is a truncation happening at a point in
                      his code that he hasn't shown us. It's very possible that replacing the
                      truncation with some form of rounding at that point would solve his
                      problem, but not knowing the exact nature of the problem, we don't know
                      what kind of rounding he might need.

                      - Ernie http://home.comcast.net/~erniew

                      Comment

                      • CBFalconer

                        #56
                        Re: converting float to double

                        William Hughes wrote:
                        Dik T. Winter wrote:
                        >"William Hughes" <wpihughes@hotm ail.comwrites:
                        >>
                        .... snip ...
                        >>>
                        >>Nothing mythical here.
                        >>>
                        >> 1 US dollar = 1374865.7 Turkish Lira
                        >>
                        >You are out of date. 1 US dollar = 1.4283 Turkish Lira.
                        >
                        No 1 US dollar = 1.4283 New Turkish Lira.
                        >
                        Yes, the convesion contant came from a table that was a few years
                        old. That hardly makes the Turkish Lira mythical.
                        Reminds me of the time I was in Paris shortly after they converted
                        to the New Franc. I was playing bridge for stakes in a local
                        bridge club, and carefully checked that the stake was in old
                        Francs. Otherwise it would have been beyond my means to risk.

                        --
                        Chuck F (cbfalconer at maineline dot net)
                        Available for consulting/temporary embedded and systems.
                        <http://cbfalconer.home .att.net>


                        Comment

                        • William Hughes

                          #57
                          Re: converting float to double


                          Ernie Wright wrote:
                          CBFalconer wrote:
                          >
                          Ernie Wright wrote:
                          CBFalconer wrote:
                          >Ben Pfaff wrote:
                          >>
                          >>For what it's worth, the round function is new in C99.
                          >>
                          >and unnecessary.
                          >>
                          > price_cents = 100 * floating_price + 0.5;
                          >
                          which is only one of several widely used rounding rules, and not
                          necessarily the one preferred for financial transactions.
                          which won't matter in the case posted by the OP. He started with a
                          constant of the form 89.13, i.e. with exactly 2 decimal places.
                          >
                          I infer that he started with a 32-bit IEEE float, which can only have
                          exactly two decimal places if they happen to be ".25", ".50" or ".75".
                          No, the "two decimal places" refers to the desired value,
                          a value known by the supplier of the stock prices.
                          What he has is a float that approximates the desired value.
                          As you note, this will rarely be exact.
                          >
                          If he were really starting with a constant in the code, he wouldn't
                          need a rounding formula. He could just erase the decimal point.
                          >
                          No, he is starting with a float provided by a vendor which
                          approximates a two decimal place value.
                          The above will capture the original value.
                          >
                          Which will only help if the OP is planning to rewrite his entire
                          application to use integers instead of doubles, an option he appears not
                          to be entertaining.
                          No. Rounding, then converting to double, does not produce the
                          same double value as a direct conversion to double. It is conjectured
                          (partially based on knowing another kludge succeeded) that this
                          will be more successful with the broken application.
                          >
                          The problem described by the OP is a truncation happening at a point in
                          his code that he hasn't shown us. It's very possible that replacing the
                          truncation with some form of rounding at that point would solve his
                          problem, but not knowing the exact nature of the problem, we don't know
                          what kind of rounding he might need.
                          Fixing the root of the problem appears to be off the table. Hence
                          the suggested kludge. The rounding used in the kludge is not
                          financial rounding.

                          - William Hughes

                          Comment

                          • Mark McIntyre

                            #58
                            Re: converting float to double

                            On 20 Dec 2006 17:33:35 -0800, in comp.lang.c , dcorbit@connx.c om
                            wrote:
                            >A 64 bit integer will correctly model currency to 18 digits (with
                            >hundredths units that gives 16 digits for the integer part).
                            Thats only 50Bn Euros, converted into Vietnamese Dong. Peanuts...
                            >In a mythical currency with 1,000,000 units per dollar, that would
                            >leave 10 billion dollar transactions accurate to the penny.
                            10Bn dollars is not a large amount. Some LCH Repoclear members will be
                            settling transactions with LCH.Clearnet for around a trillion GBP each
                            day.
                            --
                            Mark McIntyre

                            "Debugging is twice as hard as writing the code in the first place.
                            Therefore, if you write the code as cleverly as possible, you are,
                            by definition, not smart enough to debug it."
                            --Brian Kernighan

                            Comment

                            • Mark McIntyre

                              #59
                              Re: converting float to double

                              On Thu, 21 Dec 2006 02:53:22 GMT, in comp.lang.c , "Dik T. Winter"
                              <Dik.Winter@cwi .nlwrote:
                              >In article <1166666262.298 339.130380@73g2 000cwn.googlegr oups.com"Willia m Hughes" <wpihughes@hotm ail.comwrites:
                              >...
                              A 64 bit integer will correctly model currency to 18 digits (with
                              hundredths units that gives 16 digits for the integer part).
                              In a mythical currency with 1,000,000 units per dollar,
                              Nothing mythical here.

                              1 US dollar = 1374865.7 Turkish Lira
                              >
                              >You are out of date. 1 US dollar = 1.4283 Turkish Lira.
                              Old vs new Lira, both still in use.
                              Anyway, vietnamese dong are a better example...
                              So don't use 64 bit integers to calculate the world GDP in
                              Turkish Lira unless your system is tolerant of small errors.
                              >
                              >You still fail to see how the financial world is looking at it.
                              >They require exactness to some predefined unit. And if some
                              >system requires precision to the cent, do the calculations to
                              >the cent.
                              What makes it interesting is that the "predefined unit" is variable
                              by currency, market and calculation.
                              --
                              Mark McIntyre

                              "Debugging is twice as hard as writing the code in the first place.
                              Therefore, if you write the code as cleverly as possible, you are,
                              by definition, not smart enough to debug it."
                              --Brian Kernighan

                              Comment

                              • Richard Tobin

                                #60
                                Re: converting float to double

                                In article <1stko2huvfens5 o6rj482qf8d6irr fhsim@4ax.com>,
                                Mark McIntyre <markmcintyre@s pamcop.netwrote :
                                >10Bn dollars is not a large amount. Some LCH Repoclear members will be
                                >settling transactions with LCH.Clearnet for around a trillion GBP each
                                >day.
                                10 billion dollars *is* a large amount. The existence of larger
                                amounts is not relevant, assuming that's what your last sentence
                                implies (it contains too many names I've never heard before to be
                                sure).

                                -- Richard
                                --
                                "Considerat ion shall be given to the need for as many as 32 characters
                                in some alphabets" - X3.4, 1963.

                                Comment

                                Working...