From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id EDEBCBBBB for ; Sun, 19 Feb 2006 18:21:44 +0100 (CET) Received: from wproxy.gmail.com (wproxy.gmail.com [64.233.184.203]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id k1JHLh2E002671 for ; Sun, 19 Feb 2006 18:21:43 +0100 Received: by wproxy.gmail.com with SMTP id 50so733022wri for ; Sun, 19 Feb 2006 09:21:43 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:references; b=mAy6fui1w24vm9iV0DrH+Cm28dLAVtP5dyY7o5dNu2hy2aV18zgyZ7E1bu50aiZA6CbDMQlzib+oLTP4HvYLdqfucMXchnd9EkknV4J3s7s3Y+LRxgKMr4Bs8ue4kKGTRJwKiq7yGf1gwEkZxGjm34CGYF/5OY2pydbN6goBNuY= Received: by 10.64.150.16 with SMTP id x16mr251817qbd; Sun, 19 Feb 2006 09:21:42 -0800 (PST) Received: by 10.65.193.14 with HTTP; Sun, 19 Feb 2006 09:21:42 -0800 (PST) Message-ID: <8c64de0a0602190921y557577f8pc3114e0bbeb1aa56@mail.gmail.com> Date: Sun, 19 Feb 2006 12:21:42 -0500 From: "Jeremy Shute" To: "Brian Hurt" Subject: Re: [Caml-list] What library to use for arbitrary precision decimals Cc: "Joshua Smith" , caml-list@yquem.inria.fr In-Reply-To: MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_10215_2912414.1140369702896" References: X-Miltered: at nez-perce with ID 43F8A927.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; caml-list:01 computations:01 milliseconds:01 skipping:01 profiler:01 rounding:01 integers:01 computations:01 caml-list:01 beginner's:01 ocaml:01 beginners:01 bug:01 milliseconds:01 skipping:01 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.9 required=5.0 tests=HTML_20_30,HTML_MESSAGE, RCVD_BY_IP,US_DOLLARS_3 autolearn=disabled version=3.0.3 ------=_Part_10215_2912414.1140369702896 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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 $? 10= K / $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 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- tha= t > 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 > ------=_Part_10215_2912414.1140369702896 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline If you use the Int64 module as th= e 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 f= actbook 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:

$V= ND 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 currenc= ies in the $? 10K / $US 1 range.  Point: you're one locale change and = some depreciation away from overflowing when someone wants to calculate a r= atio 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 poin= t of placing an arbitrary limit on the size? 
If the prof= iler 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 co= uple of ways to handle money transactions without
> rounding errors.<= br>>
> You could use the Nums library, which provides arbitrary pr= ecision
> calculations and numbers.   But even with arbitrary prec= ision numbers,
> you still can have the situation where you get 405.0= 345 which if this
> were USD, you would still have to round if you wa= nted to pay someone
> this amount.  You will still have the arbitrary precisio= n this way,
> however.
>
> The best way to handle money (= in my experience) is to use integers.
> Then you can define conversio= n 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. &nbs= p; You can also handle
> non-decimal based currencies/instruments/tra= nsactions 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 thou= sandth of a cent (0.001
cents).  You simply do all calculation= s 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 l= arger 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 li= st. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/ca= ml-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

------=_Part_10215_2912414.1140369702896--