Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Best data type to store Financial/Monetary Values?
Forum Updated to NodeBB v4.3 + New Features

Best data type to store Financial/Monetary Values?

Scheduled Pinned Locked Moved Unsolved General and Desktop
35 Posts 13 Posters 16.7k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by VRonin
    #6

    double is more than enough if you just need 2 decimals, I wouldn't use unsigned for any financial calculations as wrapping around 0 is a nightmare, qint64 works but the precision of double is really not worth the pain going through the conversion. I store bonds cash flows (calculated by 3rd party software) in double and it never triggered any mismatch flags.

    interest, discounts and tax

    if we are talking retail shop kind of things then probably double still works. if we are talking stock market pricing models then you probably want to go to boost::multiprecision.

    Can you give me an example code of truncating the precision so i could i avoid it.

    Imagine taking the square root or a trigonometric function (sin/cos).
    boost::multiprecision gives you replacements for std::sqrt() and std::sin() that maintain the precision and do not truncate it to double. you have to take care that all methods you use do not naively truncate to double, do the calculation and then spit out a boost::multiprecision type that is now just a wrapper on double

    P.S.
    before some proper tech flames me (I'm looking at you @kshegunov ), you have to consider the trade-off between getting the, say, 8th decimal wrong in an operation using double and the implementation time and complexity of a software that uses a more precise implementation.

    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
    ~Napoleon Bonaparte

    On a crusade to banish setIndexWidget() from the holy land of Qt

    1 Reply Last reply
    1
    • E Offline
      E Offline
      Eeli K
      wrote on last edited by
      #7

      http://stackoverflow.com/questions/26764807/why-decimal-float-should-be-used-in-financial-calculations-while-it-has-rounding
      http://stackoverflow.com/questions/149033/best-way-to-store-currency-values-in-c

      etc. etc... There's no one simple solution for all cases. But about your question "isn't that inefficient?" If a Point of Sale System is what I presume it is you really don't have to think about efficiency unless you expect to have massive amounts of interactions. Especially if you do calculations and conversions client-side in a GUI application. Just be realistic about how the application/system will be used. IMO if you would be designing a critical application for a large company which would handle millions of dollars you wouldn't be asking here for advice. At least I hope so.

      1 Reply Last reply
      0
      • B Offline
        B Offline
        binsoii
        wrote on last edited by
        #8

        Hi Thanks for pointing that out. What solution should i use then? I'm still confused. Sorry, i really need help about this. Because we would be developing an Accounting System next if this POS would work out. the thing is, i don't want to proceed with a complex solution if there is a common solution developers are using to handle this matter. You said just be realistic about the system, are you suggesting to just use double? But i will need to create reports down to at least 6 decimal places. Am i overcomplicating this? if so, can you point out how to handle this based on your experience? Thanks!

        Regards!

        Chris HennesC 1 Reply Last reply
        0
        • kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by kshegunov
          #9

          I was summoned.
          I'm looking at you @VRonin ;)

          @binsoii

          Forget inefficiency, it has no bearing here.

          In my mind you have to decide between a fixed and floating point first. For finances I'd always go with fixed point if possible (especially if it's something banking related, a very touchy bunch those bank fellows ;)), as the precision isn't subject to scaling, in contrast to floating point representation.

          If you decide to use floating point however, then you need to decide how to proceed - with standard double or with a multiprecision. Ideally you'd have a type that has a lot of bits for the mantissa and somewhat few for the exponent. Unfortunately we don't live in a perfect world and double was designed to keep general purpose data, so the width of the mantissa and the exponent are fixed. I don't know if boost::multiprecision allows changing this, but in any case it's worth researching. Also when doing any operations on the numbers you have to be absolutely sure you don't carry out the calculation error into the significant digits, so it's imperative to choose appropriate algorithms.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          4
          • cfdevC Offline
            cfdevC Offline
            cfdev
            wrote on last edited by
            #10

            qreal is the best type I think.

            VRoninV 1 Reply Last reply
            0
            • cfdevC cfdev

              qreal is the best type I think.

              VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #11

              @cfdev said in Best data type to store Financial/Monetary Values?:

              qreal

              http://doc.qt.io/qt-5/qtglobal.html#qreal-typedef qreal=double or, rarely, float

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              0
              • B binsoii

                Hi Thanks for pointing that out. What solution should i use then? I'm still confused. Sorry, i really need help about this. Because we would be developing an Accounting System next if this POS would work out. the thing is, i don't want to proceed with a complex solution if there is a common solution developers are using to handle this matter. You said just be realistic about the system, are you suggesting to just use double? But i will need to create reports down to at least 6 decimal places. Am i overcomplicating this? if so, can you point out how to handle this based on your experience? Thanks!

                Regards!

                Chris HennesC Offline
                Chris HennesC Offline
                Chris Hennes
                wrote on last edited by
                #12

                @binsoii said in Best data type to store Financial/Monetary Values?:

                But i will need to create reports down to at least 6 decimal places.

                If you really have a need to generate six decimal places regardless of the magnitude of the number you cannot use a floating point number for it, as @kshegunov mentions. By construction you have a system with a fixed decimal restriction. To be honest, my advice to you is to stay far away from developing this type of software until you are intimately familiar with the details of how computers store and operate on numbers.

                Chris Hennes, Pioneer Library System

                kshegunovK B VRoninV 3 Replies Last reply
                2
                • Chris HennesC Chris Hennes

                  @binsoii said in Best data type to store Financial/Monetary Values?:

                  But i will need to create reports down to at least 6 decimal places.

                  If you really have a need to generate six decimal places regardless of the magnitude of the number you cannot use a floating point number for it, as @kshegunov mentions. By construction you have a system with a fixed decimal restriction. To be honest, my advice to you is to stay far away from developing this type of software until you are intimately familiar with the details of how computers store and operate on numbers.

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by kshegunov
                  #13

                  It's probably feasible to get away with a 34.30 fixed point signed int64, which would give about 7-8 significant decimal digits after the dot with range of a few billion. However it gets really tricky when you need to provide even some basic functions - logarithms, (square) root(s), powers for such a representation.

                  To be honest, my advice to you is to stay far away from developing this type of software until you are intimately familiar with the details of how computers store and operate on numbers.

                  That's somewhat funny (in an ironic way), because this is probably one of the most complex problems one can encounter in programming, so it's really hard to be intimately familiar. :)

                  Read and abide by the Qt Code of Conduct

                  Chris HennesC 1 Reply Last reply
                  1
                  • kshegunovK kshegunov

                    It's probably feasible to get away with a 34.30 fixed point signed int64, which would give about 7-8 significant decimal digits after the dot with range of a few billion. However it gets really tricky when you need to provide even some basic functions - logarithms, (square) root(s), powers for such a representation.

                    To be honest, my advice to you is to stay far away from developing this type of software until you are intimately familiar with the details of how computers store and operate on numbers.

                    That's somewhat funny (in an ironic way), because this is probably one of the most complex problems one can encounter in programming, so it's really hard to be intimately familiar. :)

                    Chris HennesC Offline
                    Chris HennesC Offline
                    Chris Hennes
                    wrote on last edited by
                    #14

                    @kshegunov said in Best data type to store Financial/Monetary Values?:

                    this is probably one of the most complex problems one can encounter in programming, so it's really hard to be intimately familiar. :)

                    Absolutely true! I consider myself quite well-versed in floating point numbers (at least, of the IEEE 754 flavor), and I wouldn't trust myself to work on a financial system with these requirements.

                    Chris Hennes, Pioneer Library System

                    1 Reply Last reply
                    0
                    • Chris KawaC Offline
                      Chris KawaC Offline
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on last edited by
                      #15

                      Don't use floating point types for financial data and don't re-invent a wheel implementing fixed point functions.
                      There are libraries for this. For example: fixed_point - CppCon talk: John McFarlane “fixed_point"
                      There are more if you don't like this one, just google it. But don't try to do it yourself. You'll just waste time and re-make the same mistakes people already did and fixed.

                      B 1 Reply Last reply
                      4
                      • Chris KawaC Chris Kawa

                        Don't use floating point types for financial data and don't re-invent a wheel implementing fixed point functions.
                        There are libraries for this. For example: fixed_point - CppCon talk: John McFarlane “fixed_point"
                        There are more if you don't like this one, just google it. But don't try to do it yourself. You'll just waste time and re-make the same mistakes people already did and fixed.

                        B Offline
                        B Offline
                        binsoii
                        wrote on last edited by
                        #16

                        @Chris-Kawa Thanks! i'm not trying to re-invent the wheel by the way. i just want to use the existing ones already available and easy to use, just like the System.Decimal in C# .Net sitting there ready to be taken. Why there isn't just like this already available in Qt!? :( How could this amazing framework don't have a simple thing to address this. and i really don't like the idea of using third party libraries just for this case. (I don't even know where to start integrating the example you gave, i'm really new to Qt)

                        Cheers!

                        1 Reply Last reply
                        0
                        • Chris HennesC Chris Hennes

                          @binsoii said in Best data type to store Financial/Monetary Values?:

                          But i will need to create reports down to at least 6 decimal places.

                          If you really have a need to generate six decimal places regardless of the magnitude of the number you cannot use a floating point number for it, as @kshegunov mentions. By construction you have a system with a fixed decimal restriction. To be honest, my advice to you is to stay far away from developing this type of software until you are intimately familiar with the details of how computers store and operate on numbers.

                          B Offline
                          B Offline
                          binsoii
                          wrote on last edited by
                          #17

                          @Chris-Hennes we already have an existing system, using Django and Angular to accomplish this. we used Decimal in postgresql and accounting.js library in the front end.

                          1 Reply Last reply
                          0
                          • Chris HennesC Chris Hennes

                            @binsoii said in Best data type to store Financial/Monetary Values?:

                            But i will need to create reports down to at least 6 decimal places.

                            If you really have a need to generate six decimal places regardless of the magnitude of the number you cannot use a floating point number for it, as @kshegunov mentions. By construction you have a system with a fixed decimal restriction. To be honest, my advice to you is to stay far away from developing this type of software until you are intimately familiar with the details of how computers store and operate on numbers.

                            VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by kshegunov
                            #18

                            @Chris-Hennes said in Best data type to store Financial/Monetary Values?:

                            To be honest, my advice to you is to stay far away from developing this type of software until you are intimately familiar with the details of how computers store and operate on numbers.

                            Strongly disagree. I don't know 10% of what's necessary to understand end to end encrypted communication but I use OpenSSL as I trust them to know what's necessary. Division of cognitive labor is what made humanity great. A reliable enough library (like boost) is all you need.

                            @binsoii said in Best data type to store Financial/Monetary Values?:

                            Why there isn't just like this already available in Qt!?

                            Qt integrates a lot more than you'd expect by a framework born to be a UI. Sometimes even the functionality integrated in Qt is not at par with what's available externally (see FTP support for an example).

                            @binsoii said in Best data type to store Financial/Monetary Values?:

                            and i really don't like the idea of using third party libraries just for this case

                            My suggestion involves using a library (boost) that is much closer to the standard than Qt is. I would not consider boost code quality inferior to Qt's in any aspect. <exageration>I don't think there's a C++ programmer that doesn't have boost ready to be used on his/her machine</exageration>.

                            Bottom Line:
                            if you are concerned with precision use boost::multiprecision::mpf_float_100 100 decimals (base10) precision is more that I can imagine anyone needing (you can still increase it arbitrarily btw, using boost::multiprecision::number<gmp_float<N> > where N is the number of base10 decimals precision you want)

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            Chris HennesC B 2 Replies Last reply
                            2
                            • VRoninV VRonin

                              @Chris-Hennes said in Best data type to store Financial/Monetary Values?:

                              To be honest, my advice to you is to stay far away from developing this type of software until you are intimately familiar with the details of how computers store and operate on numbers.

                              Strongly disagree. I don't know 10% of what's necessary to understand end to end encrypted communication but I use OpenSSL as I trust them to know what's necessary. Division of cognitive labor is what made humanity great. A reliable enough library (like boost) is all you need.

                              @binsoii said in Best data type to store Financial/Monetary Values?:

                              Why there isn't just like this already available in Qt!?

                              Qt integrates a lot more than you'd expect by a framework born to be a UI. Sometimes even the functionality integrated in Qt is not at par with what's available externally (see FTP support for an example).

                              @binsoii said in Best data type to store Financial/Monetary Values?:

                              and i really don't like the idea of using third party libraries just for this case

                              My suggestion involves using a library (boost) that is much closer to the standard than Qt is. I would not consider boost code quality inferior to Qt's in any aspect. <exageration>I don't think there's a C++ programmer that doesn't have boost ready to be used on his/her machine</exageration>.

                              Bottom Line:
                              if you are concerned with precision use boost::multiprecision::mpf_float_100 100 decimals (base10) precision is more that I can imagine anyone needing (you can still increase it arbitrarily btw, using boost::multiprecision::number<gmp_float<N> > where N is the number of base10 decimals precision you want)

                              Chris HennesC Offline
                              Chris HennesC Offline
                              Chris Hennes
                              wrote on last edited by
                              #19

                              @VRonin said in Best data type to store Financial/Monetary Values?:

                              Strongly disagree. I don't know 10% of what's necessary to understand end to end encrypted communication but I use OpenSSL as I trust them to know what's necessary. Division of cognitive labor is what made humanity great. A reliable enough library (like boost) is all you need.

                              In most cases you and I are in complete agreement on this point. The problem with finance is that the question isn't just reliability, it's regulation. In particular, does the regulatory environment this software is going to be used in specify when and how the rounding must take place? There are usually very, very specific requirements on software that handles financial transactions.

                              Chris Hennes, Pioneer Library System

                              1 Reply Last reply
                              3
                              • VRoninV VRonin

                                @Chris-Hennes said in Best data type to store Financial/Monetary Values?:

                                To be honest, my advice to you is to stay far away from developing this type of software until you are intimately familiar with the details of how computers store and operate on numbers.

                                Strongly disagree. I don't know 10% of what's necessary to understand end to end encrypted communication but I use OpenSSL as I trust them to know what's necessary. Division of cognitive labor is what made humanity great. A reliable enough library (like boost) is all you need.

                                @binsoii said in Best data type to store Financial/Monetary Values?:

                                Why there isn't just like this already available in Qt!?

                                Qt integrates a lot more than you'd expect by a framework born to be a UI. Sometimes even the functionality integrated in Qt is not at par with what's available externally (see FTP support for an example).

                                @binsoii said in Best data type to store Financial/Monetary Values?:

                                and i really don't like the idea of using third party libraries just for this case

                                My suggestion involves using a library (boost) that is much closer to the standard than Qt is. I would not consider boost code quality inferior to Qt's in any aspect. <exageration>I don't think there's a C++ programmer that doesn't have boost ready to be used on his/her machine</exageration>.

                                Bottom Line:
                                if you are concerned with precision use boost::multiprecision::mpf_float_100 100 decimals (base10) precision is more that I can imagine anyone needing (you can still increase it arbitrarily btw, using boost::multiprecision::number<gmp_float<N> > where N is the number of base10 decimals precision you want)

                                B Offline
                                B Offline
                                binsoii
                                wrote on last edited by binsoii
                                #20

                                @VRonin

                                if you are concerned with precision use boost::multiprecision::mpf_float_100 100 decimals (base10) precision is more that I can imagine anyone needing (you can still increase it arbitrarily btw, using boost::multiprecision::number<gmp_float<N> > where N is the number of base10 decimals precision you want)

                                Thanks a lot! boost::precision seems to be the best choice for my need. i will implement this and give an update once its done. PS (I don't where to start on how to use integrate/install this, i guess i have a lot studying to do. :D)

                                VRoninV 1 Reply Last reply
                                0
                                • B binsoii

                                  @VRonin

                                  if you are concerned with precision use boost::multiprecision::mpf_float_100 100 decimals (base10) precision is more that I can imagine anyone needing (you can still increase it arbitrarily btw, using boost::multiprecision::number<gmp_float<N> > where N is the number of base10 decimals precision you want)

                                  Thanks a lot! boost::precision seems to be the best choice for my need. i will implement this and give an update once its done. PS (I don't where to start on how to use integrate/install this, i guess i have a lot studying to do. :D)

                                  VRoninV Offline
                                  VRoninV Offline
                                  VRonin
                                  wrote on last edited by
                                  #21

                                  @binsoii said in Best data type to store Financial/Monetary Values?:

                                  I don't where to start on how to use integrate/install this, i guess i have a lot studying to do.

                                  mpf_float_* only works on GNU compilers and depends on an external library.

                                  You can use cpp_dec_float_100 it's twice as slow as mpf_float but all you have to do is download boost, add the path of booth in the INCLUDE += part of the .pro file and add #include <boost/multiprecision/cpp_dec_float.hpp> at the top of your source file

                                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                  ~Napoleon Bonaparte

                                  On a crusade to banish setIndexWidget() from the holy land of Qt

                                  kshegunovK 1 Reply Last reply
                                  1
                                  • VRoninV VRonin

                                    @binsoii said in Best data type to store Financial/Monetary Values?:

                                    I don't where to start on how to use integrate/install this, i guess i have a lot studying to do.

                                    mpf_float_* only works on GNU compilers and depends on an external library.

                                    You can use cpp_dec_float_100 it's twice as slow as mpf_float but all you have to do is download boost, add the path of booth in the INCLUDE += part of the .pro file and add #include <boost/multiprecision/cpp_dec_float.hpp> at the top of your source file

                                    kshegunovK Offline
                                    kshegunovK Offline
                                    kshegunov
                                    Moderators
                                    wrote on last edited by kshegunov
                                    #22

                                    You do understand the problem here is not with the floating point precision, but it's with the floating point itself, right?
                                    Floating point operations are exact to at most 1 epsilon which is the maximum relative difference between the two numbers. RELATIVE. I can even repeat it if it will help.

                                    Suppose you are working on a 10-base floating point computer and you have 2 digits for mantissa and 1 digit for exponent. The absolute difference between two numbers with zero exponent is 0.01 by construction. Now, what is the absolute difference between two numbers with exponent 2? Well, it is 0.01 * 100 = 1. So you trade off your absolute precision for dynamic range. For most intents and purposes this is just perfectly fine!
                                    When you need to do accounting, however, there are different regulations in place, and this trade-off is unacceptable! Your ABSOLUTE precision, can't be less than a specific amount, so that's why people use fixed-point, because the epsilon there is both relative and absolute measurement of the accuracy of an operation/number.

                                    Read and abide by the Qt Code of Conduct

                                    VRoninV 1 Reply Last reply
                                    1
                                    • kshegunovK kshegunov

                                      You do understand the problem here is not with the floating point precision, but it's with the floating point itself, right?
                                      Floating point operations are exact to at most 1 epsilon which is the maximum relative difference between the two numbers. RELATIVE. I can even repeat it if it will help.

                                      Suppose you are working on a 10-base floating point computer and you have 2 digits for mantissa and 1 digit for exponent. The absolute difference between two numbers with zero exponent is 0.01 by construction. Now, what is the absolute difference between two numbers with exponent 2? Well, it is 0.01 * 100 = 1. So you trade off your absolute precision for dynamic range. For most intents and purposes this is just perfectly fine!
                                      When you need to do accounting, however, there are different regulations in place, and this trade-off is unacceptable! Your ABSOLUTE precision, can't be less than a specific amount, so that's why people use fixed-point, because the epsilon there is both relative and absolute measurement of the accuracy of an operation/number.

                                      VRoninV Offline
                                      VRoninV Offline
                                      VRonin
                                      wrote on last edited by
                                      #23

                                      @kshegunov

                                      I'm not trying to be a smarta55, I'm honestly asking out of ignorance

                                      Can You show me an example of operation that can compromise say the 50th decimal of a boost::multiprecision::cpp_dec_float_100 ?

                                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                      ~Napoleon Bonaparte

                                      On a crusade to banish setIndexWidget() from the holy land of Qt

                                      kshegunovK 1 Reply Last reply
                                      0
                                      • VRoninV VRonin

                                        @kshegunov

                                        I'm not trying to be a smarta55, I'm honestly asking out of ignorance

                                        Can You show me an example of operation that can compromise say the 50th decimal of a boost::multiprecision::cpp_dec_float_100 ?

                                        kshegunovK Offline
                                        kshegunovK Offline
                                        kshegunov
                                        Moderators
                                        wrote on last edited by kshegunov
                                        #24

                                        @VRonin said in Best data type to store Financial/Monetary Values?:

                                        You show me an example of operation that can compromise say the 50th decimal of a boost::multiprecision::cpp_dec_float_100 ?

                                        Of course not. :)
                                        That is, unless you're about to keep numbers in the magnitude of about 10 to the 40th power. We have no physical, tangible quantity that spans those ranges. Or to put some context in, as I'm a physicist after all:

                                        • the approximate diameter of the milky way (our galaxy) is in the magnitude 10^18 km, and has about 10^11 stars
                                        • the total number of atoms in the universe is estimated to about 10^80
                                        • we know physical constants with limited precision, but let's take one of the best known - the fine-structure constant (it's the exact number behind the atomic clock), so we know that with a certainty of about 10^-9.

                                        Now look back and tell me, do you need 50 decimal places really? The point is there's already established way to represent numbers for this specific purpose, and there are regulations in place (I mean, really, they've written down in law how rounding should take place). Also note 50 decimal places would translate to about 150 bits (~18 bytes) for the mantissa alone ...!

                                        As Chris said, it's been done, it's not new, it's known. So why would you venture into the depths of arbitrary precision arithmetic (i.e. brute force the solution) to combat a problem that's been solved way back?

                                        Read and abide by the Qt Code of Conduct

                                        1 Reply Last reply
                                        2
                                        • jronaldJ Offline
                                          jronaldJ Offline
                                          jronald
                                          wrote on last edited by jronald
                                          #25

                                          Why not use cent as money unit and use int64?

                                          boost::multiprecision seems a little complex, personally I don't like the style of boost/STL, reason:

                                          1. syntax is not clear, even worse when considering the implementation
                                          2. speed is not extremely fast, for example, recently I've checked comparison of string formatting mechanisms between C and C++, the C style is more easy to use and 2x faster than C++ style. BTW, Qt and C# adopt the C way.
                                          thamT 1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved