Working with Cash and uses of Typedef

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

    Working with Cash and uses of Typedef

    I am writing a poker game which needs to work with cash. I am aware
    that there are problems with floats that make them unsuitable for
    storing money values. On top of this I may be expected to do
    operations such as £10.52 / 3. Which data type should I use instead?
    Is there an Industry standard one?

    Further to this, is anyone away of legally what the obligations would
    be when the outcome is 3.566666667? does the customer get 56 or 57p?
    Do I need to track the remaining .003333 and use it in other
    operations?

    And finally, why do I see people typedef values in C and, for example,
    use size_t rather than an int? Why is the type hidden like this?
    Surely it can lead to bugs and changing a data type later in
    development can allow bitwise and maths operations to become un-
    trustable? In my own applications I have been typdef'ing structures
    merely to remove the requirement to write "struct" everywhere and I
    see how shortening the name of unsigned long to ulng would be useful
    but I don't see it's benefit in some cases. So why do people use it?

    I'm sorry if these questions seem stupid or simple but I'm new to C
    and I can't find that many resources for C.

    Phillip Taylor
  • Morris Dovey

    #2
    Re: Working with Cash and uses of Typedef

    Philluminati wrote:
    >
    I am writing a poker game which needs to work with cash. I am aware
    that there are problems with floats that make them unsuitable for
    storing money values. On top of this I may be expected to do
    operations such as £10.52 / 3. Which data type should I use instead?
    Is there an Industry standard one?
    Depending on the range of values you need to work with, use
    either float or double.
    Further to this, is anyone away of legally what the obligations would
    be when the outcome is 3.566666667? does the customer get 56 or 57p?
    Do I need to track the remaining .003333 and use it in other
    operations?
    Choose your rounding strategy and make it public so that players
    know how things work. Making the rules of your game public is
    probably more important than the particular strategy.
    And finally, why do I see people typedef values in C and, for example,
    use size_t rather than an int? Why is the type hidden like this?
    size_t is an unsigned integer type, which may or may not resemble
    an unsigned int - while an int is a signed integer type which may
    not be large enough to hold the values required of a size_t.
    Surely it can lead to bugs and changing a data type later in
    development can allow bitwise and maths operations to become un-
    trustable? In my own applications I have been typdef'ing structures
    merely to remove the requirement to write "struct" everywhere and I
    see how shortening the name of unsigned long to ulng would be useful
    but I don't see it's benefit in some cases. So why do people use it?
    It's a communication mechanism that allows using a simple
    descriptive name for <somethingtha n perhaps could otherwise be
    applied. Sometimes it's used for emphasis or to stress how a
    programmer intends something to be used.
    I'm sorry if these questions seem stupid or simple but I'm new to C
    and I can't find that many resources for C.
    Certainly not stupid and, if you hang around here, you'll
    discover that even "simple" questions can provoke serious
    discussion of underlying nuance. :-)

    --
    Morris Dovey
    DeSoto Solar
    DeSoto, Iowa USA

    Comment

    • John Bode

      #3
      Re: Working with Cash and uses of Typedef

      On Apr 16, 7:11 am, Philluminati <Phillip.Ross.T ay...@gmail.com >
      wrote:
      I am writing a poker game which needs to work with cash. I am aware
      that there are problems with floats that make them unsuitable for
      storing money values. On top of this I may be expected to do
      operations such as £10.52 / 3. Which data type should I use instead?
      Is there an Industry standard one?
      >
      The problems with floats and doubles is that some values cannot be
      represented *exactly* in a finite number of bits, so errors in
      calculations can propagate. This becomes more of an issue when you
      start working with very big or very small numbers; for the cash values
      in a typical poker game, this shouldn't be too much of a problem.

      One alternative is to use an integer type scaled to the precision you
      desire. For example, if you need to track down to the penny, 1 == 1
      penny, so 100 = $1.00. If you need to track tenths of pennies, then 1
      == 1/10 penny, so 1000 = $1.00. The problem with this is you're
      limiting the range of values you can represent. If you're tracking
      pennies, a 16-bit int can represent values in the range -$327.68 to
      $327.68. If you're tracking tenths of pennies, that same 16 bit int
      can only represent the range -$32.768 to $32.768. A 32-bit int gives
      you more room to work with (-$2,147,483.648 to $2,147,483.648 for
      tents of pennies), but ultimately you run into the same problem.

      Another solution is to use two int types, one to track whole dollar
      amounts, the other to track pennies (or fractions of pennies). This
      is obviously a lot more work, and for what you want to do, probably
      not worth it.
      Further to this, is anyone away of legally what the obligations would
      be when the outcome is 3.566666667? does the customer get 56 or 57p?
      Do I need to track the remaining .003333 and use it in other
      operations?
      >
      If you're rounding to pennies, then that would round to 57p;
      And finally, why do I see people typedef values in C and, for example,
      use size_t rather than an int? Why is the type hidden like this?
      Portability. size_t is the type of the sizeof operator, and depending
      on the implementation, it may be the same size as unsigned int,
      unsigned long, unsigned long long, etc. By abstracting away that
      implementation detail, it frees us from having to worry about it if we
      port our code.
      Surely it can lead to bugs and changing a data type later in
      development can allow bitwise and maths operations to become un-
      trustable?
      As long as it's an integral type (which it's supposed to be), then
      those bitwise and math operations should stay the same.
      In my own applications I have been typdef'ing structures
      merely to remove the requirement to write "struct" everywhere and I
      see how shortening the name of unsigned long to ulng would be useful
      but I don't see it's benefit in some cases. So why do people use it?
      >
      Abstraction. Information hiding. Sometimes you don't want to expose
      the details behind an abstract data type to a programmer. Consider
      the FILE type in stdio.h; this is a typedef that encapsulates I/O
      state data (I/O channel, position within stream, error flags, etc.).
      Instead of manipulating this data directly, we simply pass FILE
      pointers to the various stdio routines. This has the following
      benefits:

      * Portability -- we don't have to adjust our code for
      different platforms;

      * Reliability -- by not allowing the programmer to manipulate
      state directly, there's less risk of
      error;

      * Ease of use -- calling fopen() and printf() and scanf() are
      a hell of a lot easier than manipulating I/O
      channels directly.

      Abstraction is a powerful tool, and when done properly can make life
      significantly easier.
      I'm sorry if these questions seem stupid or simple but I'm new to C
      and I can't find that many resources for C.
      >
      Phillip Taylor
      These are not stupid questions; they're very good questions. One good
      resource is the FAQ: http://www.c-faq.com/. Two of the more
      authoritative references are "The C Programming Language", 2nd ed., by
      Kernighan & Ritchie, and "C: A Reference Manual", 5th ed., by Harbison
      & Steele.

      Comment

      • Keith Thompson

        #4
        Re: Working with Cash and uses of Typedef

        Philluminati <Phillip.Ross.T aylor@gmail.com writes:
        I am writing a poker game which needs to work with cash. I am aware
        that there are problems with floats that make them unsuitable for
        storing money values. On top of this I may be expected to do
        operations such as £10.52 / 3. Which data type should I use instead?
        Is there an Industry standard one?
        Other posters have covered this reasonably well.
        Further to this, is anyone away of legally what the obligations would
        be when the outcome is 3.566666667? does the customer get 56 or 57p?
        Do I need to track the remaining .003333 and use it in other
        operations?
        This is emphatically the wrong place to ask for legal advice.
        And finally, why do I see people typedef values in C and, for example,
        use size_t rather than an int? Why is the type hidden like this?
        Surely it can lead to bugs and changing a data type later in
        development can allow bitwise and maths operations to become un-
        trustable?
        You wouldn't normally perform bitwise operations on values of type
        size_t. Values of type size_t are used to store the sizes of things.
        The underlying type *needs* to change on different implementations
        that can support larger or smaller objects. If you write your code
        properly, it will continue to work.
        In my own applications I have been typdef'ing structures
        merely to remove the requirement to write "struct" everywhere
        Many people do that, and there's nothing wrong with it; personally, I
        prefer to drop the typedef and write "struct" everywhere. Keystrokes
        are cheap.
        and I
        see how shortening the name of unsigned long to ulng would be useful
        You do? I don't. If I see "ulng" in your code, I have to go
        somewhere else to figure out what it means. If I see "unsigned long",
        there's no doubt that you're referring to the predefined type.
        but I don't see it's benefit in some cases. So why do people use it?
        Sometimes it makes sense to hide the details of a type from the code
        that uses it. See, for example, the type FILE declared in <stdio.h>.
        You don't need to know whether it's a struct or something else; all
        you need to konw is that you can declare pointers to it and pass them
        to the predefined functions.
        I'm sorry if these questions seem stupid or simple but I'm new to C
        and I can't find that many resources for C.
        The FAQ at <http://www.c-faq.com/is an excellent resource and has
        pointers to other good resources. K&R2 (Kernighan & Ritchie, "The C
        Programming Language", 2nd edition) is widely considered to be the
        best book on C (perhaps on any language).

        --
        Keith Thompson (The_Other_Keit h) <kst-u@mib.org>
        Nokia
        "We must do something. This is something. Therefore, we must do this."
        -- Antony Jay and Jonathan Lynn, "Yes Minister"

        Comment

        • Bartc

          #5
          Re: Working with Cash and uses of Typedef


          "Phillumina ti" <Phillip.Ross.T aylor@gmail.com wrote in message
          news:108eb454-d845-4a02-bc0c-62c791e200f5@s5 0g2000hsb.googl egroups.com...
          >Further to this, is anyone away of legally what the obligations would
          >be when the outcome is 3.566666667? does the customer get 56 or 57p?
          The customer might be more concerned with the missing £3.00..

          This is similar to rounding problems with VAT (17.5% of 150p is 26.25p);
          whatever they do, you can adopt the same.

          And there are likely to be discrepancies: if you round a dozen amounts then
          sum, the total could be different from summing first then rounding. You need
          to do be a bit more research somewhere other than c.l.c.
          >Do I need to track the remaining .003333 and use it in other
          >operations?
          When I did some similar stuff, accounts were stored in whole cents, even
          though intermediate calculations may have used fractional cents. After all,
          incoming and outgoing revenues were always in whole cents.

          -- Bartc



          Comment

          • user923005

            #6
            Re: Working with Cash and uses of Typedef

            On Apr 16, 5:11 am, Philluminati <Phillip.Ross.T ay...@gmail.com >
            wrote:
            I am writing a poker game which needs to work with cash. I am aware
            that there are problems with floats that make them unsuitable for
            storing money values. On top of this I may be expected to do
            operations such as £10.52 / 3. Which data type should I use instead?
            Is there an Industry standard one?

            Further to this, is anyone away of legally what the obligations would
            be when the outcome is 3.566666667?  does the customer get 56 or 57p?
            Do I need to track the remaining .003333 and use it in other
            operations?
            If it is a gambling outfit, and they are soaking the crap out of the
            poor smucks that play online, why not just go offshore to some little
            island with no sensible laws and really rip them off.
            And finally, why do I see people typedef values in C and, for example,
            use size_t rather than an int?
            A size_t and an int are quite different. For instance, size_t is
            unsigned and can represent the size of any C object. You have no such
            guarantee with int.
            Why is the type hidden like this?
            It's called an abstraction. Abstractions are created to make code
            more portable. The symbolic meaning of size_t should be obvious: it's
            an ideal unsigned integral value that can successfully represent all
            sizes.
            Surely it can lead to bugs and changing a data type later in
            development can allow bitwise and maths operations to become un-
            trustable?
            Strike that, reverse it.
            In my own applications I have been typdef'ing structures
            merely to remove the requirement to write "struct" everywhere and I
            see how shortening the name of unsigned long to ulng would be useful
            but I don't see it's benefit in some cases.
            Using a typedef on a struct is pretty much just a convenience. For C+
            + programmers, it is a little closer to home so you will see a lot
            more of them doing it.
            So why do people use it?
            To save a few keystrokes (for struct typedefs).
            I'm sorry if these questions seem stupid or simple but I'm new to C
            and I can't find that many resources for C.
            Have you read the FAQ?
            There are some good book suggestions in the FAQ as well.

            Comment

            • Flash Gordon

              #7
              Re: Working with Cash and uses of Typedef

              Morris Dovey wrote, On 16/04/08 16:03:
              Philluminati wrote:
              >I am writing a poker game which needs to work with cash. I am aware
              >that there are problems with floats that make them unsuitable for
              >storing money values. On top of this I may be expected to do
              >operations such as £10.52 / 3. Which data type should I use instead?
              >Is there an Industry standard one?
              >
              Depending on the range of values you need to work with, use
              either float or double.
              That is asking for trouble, especially with someone inexperienced enough
              to be asking the question.

              The OP should store the values as pennies in an int or long depending on
              the required range (I'm assuming that negative money is valid as it
              often is).
              >Further to this, is anyone away of legally what the obligations would
              >be when the outcome is 3.566666667? does the customer get 56 or 57p?
              >Do I need to track the remaining .003333 and use it in other
              >operations?
              >
              Choose your rounding strategy and make it public so that players
              know how things work. Making the rules of your game public is
              probably more important than the particular strategy.
              Agreed.

              <snip>
              >I'm sorry if these questions seem stupid or simple but I'm new to C
              >and I can't find that many resources for C.
              >
              Certainly not stupid and, if you hang around here, you'll
              discover that even "simple" questions can provoke serious
              discussion of underlying nuance. :-)
              As evidence we already have a disagreement :-)
              --
              Flash Gordon

              Comment

              • Morris Dovey

                #8
                Re: Working with Cash and uses of Typedef

                Flash Gordon wrote:
                >
                Morris Dovey wrote, On 16/04/08 16:03:
                Philluminati wrote:
                I am writing a poker game which needs to work with cash. I am aware
                that there are problems with floats that make them unsuitable for
                storing money values. On top of this I may be expected to do
                operations such as £10.52 / 3. Which data type should I use instead?
                Is there an Industry standard one?
                Depending on the range of values you need to work with, use
                either float or double.
                >
                That is asking for trouble, especially with someone inexperienced enough
                to be asking the question.
                Hopefully not. What /might/ be asking for trouble is for an
                inexperienced programmer to implement any kind of financial
                (sub)system without help from experienced folks...
                The OP should store the values as pennies in an int or long depending on
                the required range (I'm assuming that negative money is valid as it
                often is).
                >
                When the Philadelphia Stock Exchange added decimal trading in
                2001, there was considerable debate over currenty representation.
                After a _lot_ of really nit-picky analysis, we settled on double.
                Before bringing the decimal trading on line, we stress tested all
                the standard library functions that worked on or returned
                doubles, and we _did_ find bugs - Philluminati beware!
                As evidence we already have a disagreement :-)
                Not really - I'm perfectly happy for you to represent cash
                however it works for you. May you have enough of it to find cause
                to worry about the number of significant digits in a double! :-D

                --
                Morris Dovey
                DeSoto Solar
                DeSoto, Iowa USA

                Comment

                • Mark McIntyre

                  #9
                  Re: Working with Cash and uses of Typedef

                  Flash Gordon wrote:
                  The OP should store the values as pennies in an int or long depending on
                  the required range (I'm assuming that negative money is valid as it
                  often is).
                  A lot of people say that, but IME they tend to be people who don't work
                  in banking. I've been working in the City (of London) for 20 years now
                  and can't recall seeing a system (e-trading, stock exchange, deal
                  capture, risk management or back office) that actually worked in pennies.

                  What you /do/ see is data interchange formats that work without the
                  decimal point. It can be a pig when you've got eg Eurobonds and USTs in
                  the same feed - the former are measured to the nearest penny, the latter
                  to the nearest 32nd (or 128th). Usually you have a flag somewhere else
                  in the file to tell you where to insert the decimal, and how to treat
                  the RHS (eg 10131 if its a UST means 101 and 31/32nds, whereas for a
                  eurobond it would mean 101.31)
                  >>Further to this, is anyone away of legally what the obligations would
                  >>be when the outcome is 3.566666667? does the customer get 56 or 57p?
                  >>Do I need to track the remaining .003333 and use it in other
                  >>operations?
                  >>
                  >Choose your rounding strategy and make it public so that players
                  >know how things work. Making the rules of your game public is
                  >probably more important than the particular strategy.
                  >
                  Agreed.
                  Agreed too - though there are several common strategies which you should
                  consider as people will understand them:
                  - round up if the significant digit is 5 or larger eg 1.005 -1.01
                  - round up if the integer part is even eg 1.005 -1.00, 2.005 -2.01
                  - truncate at the Nth decimal irrespective. 1.00999999 -1.00
                  >>I'm sorry if these questions seem stupid or simple but I'm new to C
                  >>and I can't find that many resources for C.
                  These questions aren't really C specific however - comp.programmin g
                  would probably be as good a place.

                  Comment

                  • Flash Gordon

                    #10
                    Re: Working with Cash and uses of Typedef

                    Morris Dovey wrote, On 16/04/08 23:38:
                    Flash Gordon wrote:
                    >Morris Dovey wrote, On 16/04/08 16:03:
                    >>Philluminat i wrote:
                    >>>I am writing a poker game which needs to work with cash. I am aware
                    >>>that there are problems with floats that make them unsuitable for
                    >>>storing money values. On top of this I may be expected to do
                    >>>operations such as £10.52 / 3. Which data type should I use instead?
                    >>>Is there an Industry standard one?
                    >>Depending on the range of values you need to work with, use
                    >>either float or double.
                    >That is asking for trouble, especially with someone inexperienced enough
                    >to be asking the question.
                    >
                    Hopefully not. What /might/ be asking for trouble is for an
                    inexperienced programmer to implement any kind of financial
                    (sub)system without help from experienced folks...
                    Well, we are talking about someone working on a system dealing with
                    monetary values...
                    >The OP should store the values as pennies in an int or long depending on
                    >the required range (I'm assuming that negative money is valid as it
                    >often is).
                    >>
                    When the Philadelphia Stock Exchange added decimal trading in
                    2001, there was considerable debate over currenty representation.
                    After a _lot_ of really nit-picky analysis, we settled on double.
                    I know it can be done, I also know how easy it is to hit problems...
                    Before bringing the decimal trading on line, we stress tested all
                    the standard library functions that worked on or returned
                    doubles, and we _did_ find bugs - Philluminati beware!
                    and you did hit problems :-)

                    I'm sure you also worked out how to handle them appropriately.
                    >As evidence we already have a disagreement :-)
                    >
                    Not really - I'm perfectly happy for you to represent cash
                    however it works for you. May you have enough of it to find cause
                    to worry about the number of significant digits in a double! :-D
                    That's not a problem, if I hit that level I will be able to afford to
                    buy a computer with more significant digits and get the SW written for
                    it :-)
                    --
                    Flash Gordon

                    Comment

                    • user923005

                      #11
                      Re: Working with Cash and uses of Typedef

                      On Apr 16, 3:15 pm, Flash Gordon <s...@flash-gordon.me.ukwro te:
                      Morris Dovey wrote, On 16/04/08 23:38:
                      >
                      >
                      >
                      >
                      >
                      Flash Gordon wrote:
                      Morris Dovey wrote, On 16/04/08 16:03:
                      >Philluminati wrote:
                      >>I am writing a poker game which needs to work with cash. I am aware
                      >>that there are problems with floats that make them unsuitable for
                      >>storing money values. On top of this I may be expected to do
                      >>operations such as £10.52 / 3. Which data type should I use instead?
                      >>Is there an Industry standard one?
                      >Depending on the range of values you need to work with, use
                      >either float or double.
                      That is asking for trouble, especially with someone inexperienced enough
                      to be asking the question.
                      >
                      Hopefully not. What /might/ be asking for trouble is for an
                      inexperienced programmer to implement any kind of financial
                      (sub)system without help from experienced folks...
                      >
                      Well, we are talking about someone working on a system dealing with
                      monetary values...
                      >
                      The OP should store the values as pennies in an int or long depending on
                      the required range (I'm assuming that negative money is valid as it
                      often is).
                      >
                      When the Philadelphia Stock Exchange added decimal trading in
                      2001, there was considerable debate over currenty representation.
                      After a _lot_ of really nit-picky analysis, we settled on double.
                      >
                      I know it can be done, I also know how easy it is to hit problems...
                      >
                      Before bringing the decimal trading on line, we stress tested all
                      the standard library functions that worked on or returned
                      doubles, and we _did_ find bugs - Philluminati beware!
                      >
                      and you did hit problems :-)
                      >
                      I'm sure you also worked out how to handle them appropriately.
                      >
                      As evidence we already have a disagreement :-)
                      >
                      Not really - I'm perfectly happy for you to represent cash
                      however it works for you. May you have enough of it to find cause
                      to worry about the number of significant digits in a double! :-D
                      >
                      That's not a problem, if I hit that level I will be able to afford to
                      buy a computer with more significant digits and get the SW written for
                      it :-)
                      People are sometimes surprised when adding a column of numbers
                      forwards and backwards gives different answers (as floating point
                      definitely will for non-integral totals).

                      For a GAAP accounting package, I would definitely use decimal
                      arithmetic, if possible.

                      For some kinds of financial operations exact reproducability is very
                      important (e.g. 'how much money is in my account'). For others,
                      perhaps not as important (e.g. according to this derivative, we should
                      buy pork belly futures).

                      There is no magic bullet for financial operations, and I would
                      certainly expect anyone who is handling *my* money to be absurdly
                      careful to do everything as precisely and correctly as possible.

                      Comment

                      • Flash Gordon

                        #12
                        Re: Working with Cash and uses of Typedef

                        Mark McIntyre wrote, On 16/04/08 23:47:
                        Flash Gordon wrote:
                        >The OP should store the values as pennies in an int or long depending
                        >on the required range (I'm assuming that negative money is valid as it
                        >often is).
                        >
                        A lot of people say that, but IME they tend to be people who don't work
                        in banking.
                        You are correct in thinking that I don't, although I do work on
                        financial systems and some of the time we do store (and calculate with)
                        values in pennies. At other times it is in other currencies. Sometimes
                        we work with integral values of pennies in doubles.
                        I've been working in the City (of London) for 20 years now
                        and can't recall seeing a system (e-trading, stock exchange, deal
                        capture, risk management or back office) that actually worked in pennies.
                        Well, I'll admit you work on bigger financial systems than me.

                        My experience is that it is easier to get it right when working with a
                        scaled number in an integer type, so when the range is sufficient that
                        is what I would do and recommend.
                        What you /do/ see is data interchange formats that work without the
                        decimal point. It can be a pig when you've got eg Eurobonds and USTs in
                        the same feed - the former are measured to the nearest penny, the latter
                        to the nearest 32nd (or 128th). Usually you have a flag somewhere else
                        in the file to tell you where to insert the decimal, and how to treat
                        the RHS (eg 10131 if its a UST means 101 and 31/32nds, whereas for a
                        eurobond it would mean 101.31)
                        Oh yes, file formats can be fun. We do a fair bit of integration with
                        other systems (not the same systems as you) and I'm sure some are
                        designed to be a pain!
                        >>>Further to this, is anyone away of legally what the obligations would
                        >>>be when the outcome is 3.566666667? does the customer get 56 or 57p?
                        >>>Do I need to track the remaining .003333 and use it in other
                        >>>operations ?
                        >>>
                        >>Choose your rounding strategy and make it public so that players
                        >>know how things work. Making the rules of your game public is
                        >>probably more important than the particular strategy.
                        >>
                        >Agreed.
                        >
                        Agreed too - though there are several common strategies which you should
                        consider as people will understand them:
                        - round up if the significant digit is 5 or larger eg 1.005 -1.01
                        - round up if the integer part is even eg 1.005 -1.00, 2.005 -2.01
                        - truncate at the Nth decimal irrespective. 1.00999999 -1.00
                        Also define how this works with negative.
                        >>>I'm sorry if these questions seem stupid or simple but I'm new to C
                        >>>and I can't find that many resources for C.
                        >
                        These questions aren't really C specific however - comp.programmin g
                        would probably be as good a place.
                        Yes, this part is more appropriate there, or possibly in a group
                        dedicated to poker!
                        --
                        Flash Gordon

                        Comment

                        • user923005

                          #13
                          Re: Working with Cash and uses of Typedef

                          On Apr 16, 4:17 pm, Flash Gordon <s...@flash-gordon.me.ukwro te:
                          Mark McIntyre wrote, On 16/04/08 23:47:
                          >
                          Flash Gordon wrote:
                          The OP should store the values as pennies in an int or long depending
                          on the required range (I'm assuming that negative money is valid as it
                          often is).
                          >
                          A lot of people say that, but IME they tend to be people who don't work
                          in banking.
                          >
                          You are correct in thinking that I don't, although I do work on
                          financial systems and some of the time we do store (and calculate with)
                          values in pennies. At other times it is in other currencies. Sometimes
                          we work with integral values of pennies in doubles.
                          I have seen financial source code that performs accouting using
                          integral pennies from two major insurance companies.
                          [snip]

                          Comment

                          • Ernie Wright

                            #14
                            Re: Working with Cash and uses of Typedef

                            Morris Dovey wrote:
                            Flash Gordon wrote:
                            >
                            >>The OP should store the values as pennies in an int or long depending on
                            >>the required range (I'm assuming that negative money is valid as it
                            >>often is).
                            >
                            When the Philadelphia Stock Exchange added decimal trading in
                            2001, there was considerable debate over currenty representation.
                            After a _lot_ of really nit-picky analysis, we settled on double.
                            Before bringing the decimal trading on line, we stress tested all
                            the standard library functions that worked on or returned
                            doubles, and we _did_ find bugs - Philluminati beware!
                            >
                            >>As evidence we already have a disagreement :-)
                            >
                            Not really - I'm perfectly happy for you to represent cash
                            however it works for you. May you have enough of it to find cause
                            to worry about the number of significant digits in a double! :-D
                            Yabbut, the problem with floating-point representation of money isn't
                            the number of significant digits. The problem is that most decimal
                            fractions can't be represented exactly in binary.

                            0.10, for example, is a repeating fraction in binary, specifically

                            .0001 1001 1001 ...

                            or in hex,

                            .19999999...

                            In practice, the most common representation in a double is slightly
                            larger than 0.10 decimal:

                            .1999999999999A

                            in hex, or

                            0.1000000000000 000055511151231 257827021181583 404541015625

                            (exactly) in decimal.

                            The quick fix most often suggested, and it's been suggested several
                            times in this thread already, is to scale the amounts. Presumably this
                            makes everything better because the representation no longer contains
                            fractions. But it doesn't actually address the problem at all.

                            Scaling by 100 (representing money as an integral number of cents, say,
                            instead of dollars) merely shifts the problem two decimal places to the
                            right. A badly implemented calculation that loses one digit of precision
                            every N iterations can cause an error of the same magnitude after 3N
                            iterations with amounts scaled by 100.

                            The issue is fairness of rounding, and you face this regardless of how
                            you choose to represent the amounts.

                            There really isn't anything special about money. Working with money
                            amounts merely calls attention to the more general problem of accuracy.
                            If you want good numerical results, you have to apply sound numerical
                            methods. Using integers, or scaling by 100, won't magically make your
                            methods sound.

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

                            Comment

                            • Flash Gordon

                              #15
                              Re: Working with Cash and uses of Typedef

                              Ernie Wright wrote, On 17/04/08 16:43:
                              Morris Dovey wrote:
                              >
                              >Flash Gordon wrote:
                              >>
                              >>The OP should store the values as pennies in an int or long depending on
                              >>the required range (I'm assuming that negative money is valid as it
                              >>often is).
                              >>
                              >When the Philadelphia Stock Exchange added decimal trading in
                              >2001, there was considerable debate over currenty representation.
                              >After a _lot_ of really nit-picky analysis, we settled on double.
                              >Before bringing the decimal trading on line, we stress tested all
                              >the standard library functions that worked on or returned
                              >doubles, and we _did_ find bugs - Philluminati beware!
                              >>
                              >>As evidence we already have a disagreement :-)
                              >>
                              >Not really - I'm perfectly happy for you to represent cash
                              >however it works for you. May you have enough of it to find cause
                              >to worry about the number of significant digits in a double! :-D
                              >
                              Yabbut, the problem with floating-point representation of money isn't
                              the number of significant digits. The problem is that most decimal
                              fractions can't be represented exactly in binary.
                              >
                              0.10, for example, is a repeating fraction in binary, specifically
                              >
                              .0001 1001 1001 ...
                              <snip>

                              I suspect Eric knows this.
                              Scaling by 100 (representing money as an integral number of cents, say,
                              instead of dollars) merely shifts the problem two decimal places to the
                              right.
                              In many situations with money it *does* solve the problem, because often
                              the problem explicitly states that you do not have any more decimal
                              places. OK, you have to arrange for appropriate rounding on division,
                              but that is easy enough.
                              A badly implemented calculation that loses one digit of precision
                              every N iterations can cause an error of the same magnitude after 3N
                              iterations with amounts scaled by 100.
                              >
                              The issue is fairness of rounding, and you face this regardless of how
                              you choose to represent the amounts.
                              >
                              There really isn't anything special about money. Working with money
                              amounts merely calls attention to the more general problem of accuracy.
                              With money there are often legal requirements specifying exactly what
                              you do, and that is often something like throw away the fractional
                              pennies. Sometimes it is throw away the pennies entirely (I've been
                              required by the UK government to do this for data being sent to the UK
                              government).
                              If you want good numerical results, you have to apply sound numerical
                              methods. Using integers, or scaling by 100, won't magically make your
                              methods sound.
                              Sometimes you have to deliberately use numerically unsound methods. E.g.
                              take 17.5% of each value, throw away any fractional pennies and then do
                              the summation.

                              My experience working on financial systems is that you are often
                              specifically required to not deal with anything smaller than a certain
                              size, and you are generally required to loose the extra precision sooner
                              rather than later in the calculation. Of course, as someone else pointed
                              out there are times where the accuracy does not really matter because
                              people will not care about the likelihood of making an extra penny on a
                              1000 pound investment.
                              --
                              Flash Gordon

                              Comment

                              Working...