* What library to use for arbitrary precision decimals @ 2006-02-19 13:43 Joshua Smith 2006-02-19 15:44 ` [Caml-list] " Brian Hurt 0 siblings, 1 reply; 9+ messages in thread From: Joshua Smith @ 2006-02-19 13:43 UTC (permalink / raw) To: caml-list There are a couple of ways to handle money transactions without rounding errors. You could use the Nums library, which provides arbitrary precision calculations and numbers. But even with arbitrary precision numbers, you still can have the situation where you get 405.0345 which if this were USD, you would still have to round if you wanted to pay someone this amount. You will still have the arbitrary precision this way, however. The best way to handle money (in my experience) is to use integers. Then you can define conversion functions but only have to convert it to decimal for display purposes. That way, even if you do a million transactions you won't lose any information. You can also handle non-decimal based currencies/instruments/transactions that way[1] HTH -jbs [1] yes, there are a (thank god shrinking number) of commodities and stuff like that in the world that don't use decimal prices. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] What library to use for arbitrary precision decimals 2006-02-19 13:43 What library to use for arbitrary precision decimals Joshua Smith @ 2006-02-19 15:44 ` Brian Hurt 2006-02-19 16:38 ` Richard Jones 2006-02-19 17:21 ` Jeremy Shute 0 siblings, 2 replies; 9+ messages in thread From: Brian Hurt @ 2006-02-19 15:44 UTC (permalink / raw) To: Joshua Smith; +Cc: caml-list On Sun, 19 Feb 2006, Joshua Smith wrote: > There are a couple of ways to handle money transactions without > rounding errors. > > You could use the Nums library, which provides arbitrary precision > calculations and numbers. But even with arbitrary precision numbers, > you still can have the situation where you get 405.0345 which if this > were USD, you would still have to round if you wanted to pay someone > this amount. You will still have the arbitrary precision this way, > however. > > The best way to handle money (in my experience) is to use integers. > Then you can define conversion functions but only have to convert it > to decimal for display purposes. That way, even if you do a million > transactions you won't lose any information. You can also handle > non-decimal based currencies/instruments/transactions that way[1] I agree with this recommendation. The basic idea is that you use fixed point. Say you want to be accurate to one thousandth of a cent (0.001 cents). You simply do all calculations in terms of millicents. So the integer 1 represents one millicent. One penny is represented as the integer 1,000- one thousand millicents. The amount $2,345.67 is represented by the integer 234,567,000. If you use the Int64 module as the basis for your computations, you can hold values up to $184,467,440,737,095.51 in size. This is larger than the world's GDP, so it should be large enough. 32 bits isn't enough- that only allows you to hold values up to $42,949.67. Brian ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] What library to use for arbitrary precision decimals 2006-02-19 15:44 ` [Caml-list] " Brian Hurt @ 2006-02-19 16:38 ` Richard Jones 2006-02-19 16:53 ` Brian Hurt 2006-02-19 17:21 ` Jeremy Shute 1 sibling, 1 reply; 9+ messages in thread From: Richard Jones @ 2006-02-19 16:38 UTC (permalink / raw) To: caml-list Before we go too far down the currency track (where I agree, using integers is the way to go), my actual requirement is for a natural OCaml mapping for the PostgreSQL NUMERIC/DECIMAL type: http://www.postgresql.org/docs/current/interactive/datatype.html#DATATYPE-NUMERIC-DECIMAL The database can define types like NUMERIC(6,4) which means 6 decimal digits in total, 4 of them after the decimal point -- for example, 12.3456 There doesn't seem to me to be a good natural map for this type in the stdlib. Rich. PS. You can find latest progress on PG'OCaml here: http://merjis.com/tmp/pgocaml-0.3.tar.gz I've already converted a few of our bigger programs to use this library. -- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] What library to use for arbitrary precision decimals 2006-02-19 16:38 ` Richard Jones @ 2006-02-19 16:53 ` Brian Hurt 2006-02-19 17:00 ` Richard Jones 0 siblings, 1 reply; 9+ messages in thread From: Brian Hurt @ 2006-02-19 16:53 UTC (permalink / raw) To: Richard Jones; +Cc: caml-list On Sun, 19 Feb 2006, Richard Jones wrote: > > Before we go too far down the currency track (where I agree, using > integers is the way to go), my actual requirement is for a natural > OCaml mapping for the PostgreSQL NUMERIC/DECIMAL type: > > http://www.postgresql.org/docs/current/interactive/datatype.html#DATATYPE-NUMERIC-DECIMAL > > The database can define types like NUMERIC(6,4) which means 6 decimal > digits in total, 4 of them after the decimal point -- for example, > 12.3456 Hmm. There are problems definin that library. What are the semantics? If I add a NUMERIC(6,4) (2 digits to the left of the point and 4 to the righ) and a NUMERIC(7,2) (5 digits to the left of the point and 2 to the right), what precision is the result? NUMERIC(4,2) (2 digits to the left of the point and 2 to the right)? NUMERIC(9,4) (5 digits to the left of the point and 4 digits to the right)? How does roundoff work? If I take the NUMERIC(6,4) number 62.0000 and multiply it by the NUMERIC(6,4) number 02.0000, what answer do I get? The NUMERIC(6,4) number 24.000? The NUMERIC(7,4) number 124.000? Or does it throw an exception? > > There doesn't seem to me to be a good natural map for this type in the > stdlib. If decimal roundoff isn't important, I'd be tempted to go for floats. I don't know if this is true or not. Brian ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] What library to use for arbitrary precision decimals 2006-02-19 16:53 ` Brian Hurt @ 2006-02-19 17:00 ` Richard Jones 2006-02-19 17:13 ` Richard Jones 0 siblings, 1 reply; 9+ messages in thread From: Richard Jones @ 2006-02-19 17:00 UTC (permalink / raw) To: Brian Hurt; +Cc: caml-list On Sun, Feb 19, 2006 at 10:53:47AM -0600, Brian Hurt wrote: > Hmm. There are problems definin that library. What are the semantics? > If I add a NUMERIC(6,4) (2 digits to the left of the point and 4 to the > righ) and a NUMERIC(7,2) (5 digits to the left of the point and 2 to the > right), what precision is the result? NUMERIC(4,2) (2 digits to the left > of the point and 2 to the right)? NUMERIC(9,4) (5 digits to the left of > the point and 4 digits to the right)? How does roundoff work? If I take > the NUMERIC(6,4) number 62.0000 and multiply it by the NUMERIC(6,4) number > 02.0000, what answer do I get? The NUMERIC(6,4) number 24.000? The > NUMERIC(7,4) number 124.000? Or does it throw an exception? Well yes indeed. I'm quite sure there's a SQL specification somewhere which answers this :-) Rich. -- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] What library to use for arbitrary precision decimals 2006-02-19 17:00 ` Richard Jones @ 2006-02-19 17:13 ` Richard Jones 0 siblings, 0 replies; 9+ messages in thread From: Richard Jones @ 2006-02-19 17:13 UTC (permalink / raw) To: caml-list I checked the standard and for standard operations on NUMERIC, the precision of the result is implementation defined, while the scale depends on the operation: + - S_r = max (S_1, S_2) * S_r = S_1 + S_2 / S_r = implementation defined where S_r = scale of the result, and S_1 = scale of the first operand and S_2 = scale of the second operand. Rich. -- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] What library to use for arbitrary precision decimals 2006-02-19 15:44 ` [Caml-list] " Brian Hurt 2006-02-19 16:38 ` Richard Jones @ 2006-02-19 17:21 ` Jeremy Shute 2006-02-19 18:31 ` Brian Hurt 1 sibling, 1 reply; 9+ messages in thread From: Jeremy Shute @ 2006-02-19 17:21 UTC (permalink / raw) To: Brian Hurt; +Cc: Joshua Smith, caml-list [-- Attachment #1: Type: text/plain, Size: 2991 bytes --] If you use the Int64 module as the basis for your computations, you can hold values up to $184,467,440,737,095.51 in size. How many Vietnamese Dongs is that? Some CIA factbook estimates of the GDP of the world: $US 5.938e+13 One dollar will buy you a lot of Vietnamese Dongs: $VND 1.5838e+4 So, the GDP of the world (a popular number, to be sure) is about: $VND 9.4046e+17 ...and the the max signed int64 is around... 9.2234e+18 This is not an isolated case, there are quite a few currencies in the $? 10K / $US 1 range. Point: you're one locale change and some depreciation away from overflowing when someone wants to calculate a ratio for analysis. Why not use a big int? If you're keeping things in a database, you're going to be spending milliseconds skipping across the disk for this and that -- what's the point of placing an arbitrary limit on the size? If the profiler shows that you're eating cycles like candy, optimize your routine back down. Jeremy On 2/19/06, Brian Hurt <bhurt@spnz.org> wrote: > > > > On Sun, 19 Feb 2006, Joshua Smith wrote: > > > There are a couple of ways to handle money transactions without > > rounding errors. > > > > You could use the Nums library, which provides arbitrary precision > > calculations and numbers. But even with arbitrary precision numbers, > > you still can have the situation where you get 405.0345 which if this > > were USD, you would still have to round if you wanted to pay someone > > this amount. You will still have the arbitrary precision this way, > > however. > > > > The best way to handle money (in my experience) is to use integers. > > Then you can define conversion functions but only have to convert it > > to decimal for display purposes. That way, even if you do a million > > transactions you won't lose any information. You can also handle > > non-decimal based currencies/instruments/transactions that way[1] > > I agree with this recommendation. The basic idea is that you use fixed > point. Say you want to be accurate to one thousandth of a cent (0.001 > cents). You simply do all calculations in terms of millicents. So the > integer 1 represents one millicent. One penny is represented as the > integer 1,000- one thousand millicents. The amount $2,345.67 is > represented by the integer 234,567,000. > > If you use the Int64 module as the basis for your computations, you can > hold values up to $184,467,440,737,095.51 in size. This is larger than > the world's GDP, so it should be large enough. 32 bits isn't enough- that > only allows you to hold values up to $42,949.67. > > Brian > > _______________________________________________ > Caml-list mailing list. Subscription management: > http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list > Archives: http://caml.inria.fr > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > [-- Attachment #2: Type: text/html, Size: 3880 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] What library to use for arbitrary precision decimals 2006-02-19 17:21 ` Jeremy Shute @ 2006-02-19 18:31 ` Brian Hurt 0 siblings, 0 replies; 9+ messages in thread From: Brian Hurt @ 2006-02-19 18:31 UTC (permalink / raw) To: Jeremy Shute; +Cc: Joshua Smith, caml-list On Sun, 19 Feb 2006, Jeremy Shute wrote: > If you use the Int64 module as the basis for your computations, you can > hold values up to $184,467,440,737,095.51 in size. > > How many Vietnamese Dongs is that? Some CIA factbook estimates of the GDP > of the world: > > $US 5.938e+13 > > One dollar will buy you a lot of Vietnamese Dongs: > > $VND 1.5838e+4 > > So, the GDP of the world (a popular number, to be sure) is about: > > $VND 9.4046e+17 > > ...and the the max signed int64 is around... > > 9.2234e+18 > > This is not an isolated case, there are quite a few currencies in the $? 10K > / $US 1 range. Point: you're one locale change and some depreciation away > from overflowing when someone wants to calculate a ratio for analysis. Why > not use a big int? You're right that if you're needing to calculate the World GDP, or even the American debt, you may need more bits. Although I was doing stuff in millipennies, simply doing stuff in centipennies still leaves you enough information to round to the nearest penny correctly, and gives you another order of magnitude headroom. The reason to use Int64 instead of Bigint is performance. This may or may not be an issue. Although I note that both Bigint and Int64 performance is going to way stomp BCD performance. Brian ^ permalink raw reply [flat|nested] 9+ messages in thread
* What library to use for arbitrary precision decimals @ 2006-02-19 10:18 Richard Jones 0 siblings, 0 replies; 9+ messages in thread From: Richard Jones @ 2006-02-19 10:18 UTC (permalink / raw) To: caml-list What library / type should I be using for arbitrary precision decimals - ie. floats where I can store things like currency amounts without getting rounding errors? Rich. -- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-02-19 18:31 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-02-19 13:43 What library to use for arbitrary precision decimals Joshua Smith 2006-02-19 15:44 ` [Caml-list] " Brian Hurt 2006-02-19 16:38 ` Richard Jones 2006-02-19 16:53 ` Brian Hurt 2006-02-19 17:00 ` Richard Jones 2006-02-19 17:13 ` Richard Jones 2006-02-19 17:21 ` Jeremy Shute 2006-02-19 18:31 ` Brian Hurt -- strict thread matches above, loose matches on Subject: below -- 2006-02-19 10:18 Richard Jones
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox