This page is no longer maintained — Please continue to the home page at www.scala-lang.org

0.4 * 0.4 is not 0.16, why? (is this a bug?)

22 replies
Himanshu
Joined: 2009-10-27,
User offline. Last seen 42 years 45 weeks ago.
scala> 0.4*0.4
res0: Double = 0.16000000000000003 //NOT 0.16

scala> 0.7*0.4
res1: Double = 0.27999999999999997 //NOT 0.28

I used scala-2.8.0.Beta1-prerelease.
dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
No, this is not a bug, this is floating point. Look it up. It will happen in pretty much any language.
If you need accuracy as well as precision, then try using BigDecimal instead. It is much slower, though.
On Tue, Mar 30, 2010 at 12:52 AM, Himanshu <g [dot] himanshu [at] gmail [dot] com> wrote:
scala> 0.4*0.4
res0: Double = 0.16000000000000003 //NOT 0.16

scala> 0.7*0.4
res1: Double = 0.27999999999999997 //NOT 0.28

I used scala-2.8.0.Beta1-prerelease.



--
Daniel C. Sobral

I travel to the future all the time.
dlandis
Joined: 2009-09-30,
User offline. Last seen 3 years 3 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)

Maybe you could use a Java BigDecimal

On Mon, Mar 29, 2010 at 11:52 PM, Himanshu wrote:
> scala> 0.4*0.4
> res0: Double = 0.16000000000000003 //NOT 0.16
>
> scala> 0.7*0.4
> res1: Double = 0.27999999999999997 //NOT 0.28
>
> I used scala-2.8.0.Beta1-prerelease.
>

Himanshu
Joined: 2009-10-27,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
Thanks Daniel and David.. I just tried it on java also, results are exactly the same :)
James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
Here it is in GHC Haskell
Prelude> 0.4 * 0.40.16000000000000003
And Python>>> 0.4 * 0.40.16000000000000003
And gcc C++
#include <iostream>#include <iomanip>
using namespace std;
int main(int argc, char** argv) {       cout << setprecision(55) << 0.4 * 0.4 << endl;}0.16000000000000003108624468950438313186168670654296875
You're going to have to file a lot of bugs.
On Mon, Mar 29, 2010 at 11:32 PM, Himanshu <g [dot] himanshu [at] gmail [dot] com> wrote:
Thanks Daniel and David.. I just tried it on java also, results are exactly the same :)

Lex
Joined: 2010-02-28,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)

You are in a world of surprises. Here is another one with floating
point numbers:

val n = 1.0/0.0 - 1.0/0.0
if (n > 0.0) println("ok")
else if (n < 0.0) println("ok")
else if (n == 0.0) println("ok")
else println("oops")

Also there are things like round off errors which can kill the
accuracy of your result very quickly. Because of this many math
formulas cannot be used directly and need special algorithms.

On Mon, Mar 29, 2010 at 11:52 PM, Himanshu wrote:
> scala> 0.4*0.4
> res0: Double = 0.16000000000000003 //NOT 0.16
>
> scala> 0.7*0.4
> res1: Double = 0.27999999999999997 //NOT 0.28
>
> I used scala-2.8.0.Beta1-prerelease.
>

dlandis
Joined: 2009-09-30,
User offline. Last seen 3 years 3 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)

On Tue, Mar 30, 2010 at 2:32 AM, Himanshu wrote:
> Thanks Daniel and David.. I just tried it on java also, results are exactly
> the same :)
>

System.out.println(BigDecimal.valueOf(.4).multiply(BigDecimal.valueOf(.4)));
System.out.println(BigDecimal.valueOf(.4).multiply(BigDecimal.valueOf(.7)));

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
I know ABC uses bigdecimal by default (and who here ever heard of it? :). I think Ruby and TCL might do it too, not sure.

On Tue, Mar 30, 2010 at 11:48 AM, James Iry <jamesiry [at] gmail [dot] com> wrote:
Here it is in GHC Haskell
Prelude> 0.4 * 0.40.16000000000000003
And Python>>> 0.4 * 0.40.16000000000000003
And gcc C++
#include <iostream>#include <iomanip>
using namespace std;
int main(int argc, char** argv) {       cout << setprecision(55) << 0.4 * 0.4 << endl;}0.16000000000000003108624468950438313186168670654296875
You're going to have to file a lot of bugs.
On Mon, Mar 29, 2010 at 11:32 PM, Himanshu <g [dot] himanshu [at] gmail [dot] com> wrote:
Thanks Daniel and David.. I just tried it on java also, results are exactly the same :)




--
Daniel C. Sobral

I travel to the future all the time.
Federico Silva
Joined: 2010-03-31,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)

On Tue, Mar 30, 2010 at 16:14, Daniel Sobral wrote:
> I know ABC uses bigdecimal by default (and who here ever heard of it? :). I
> think Ruby

yep

$ irb
>> 0.4*0.4
=> 0.16
>>

> and TCL might do it too, not sure.
>
> On Tue, Mar 30, 2010 at 11:48 AM, James Iry wrote:
>>
>> Here it is in GHC Haskell
>> Prelude> 0.4 * 0.4
>> 0.16000000000000003
>> And Python
>> >>> 0.4 * 0.4
>> 0.16000000000000003
>> And gcc C++
>> #include
>> #include
>> using namespace std;
>> int main(int argc, char** argv) {
>>       cout << setprecision(55) << 0.4 * 0.4 << endl;
>> }
>> 0.16000000000000003108624468950438313186168670654296875
>> You're going to have to file a lot of bugs.
>> On Mon, Mar 29, 2010 at 11:32 PM, Himanshu wrote:
>>>
>>> Thanks Daniel and David.. I just tried it on java also, results are
>>> exactly the same :)
>>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
>

James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
Nope. Your string is just being truncated
irb(main):014:0> "%.55f" % (0.4 * 0.4)=> "0.1600000000000000310862446895043831318616867065429687500"

On Wed, Mar 31, 2010 at 2:35 PM, Federico Silva <fede [dot] silva [at] gmail [dot] com> wrote:
On Tue, Mar 30, 2010 at 16:14, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
> I know ABC uses bigdecimal by default (and who here ever heard of it? :). I
> think Ruby

yep

$ irb
>> 0.4*0.4
=> 0.16
>>


> and TCL might do it too, not sure.
>
> On Tue, Mar 30, 2010 at 11:48 AM, James Iry <jamesiry [at] gmail [dot] com> wrote:
>>
>> Here it is in GHC Haskell
>> Prelude> 0.4 * 0.4
>> 0.16000000000000003
>> And Python
>> >>> 0.4 * 0.4
>> 0.16000000000000003
>> And gcc C++
>> #include <iostream>
>> #include <iomanip>
>> using namespace std;
>> int main(int argc, char** argv) {
>>       cout << setprecision(55) << 0.4 * 0.4 << endl;
>> }
>> 0.16000000000000003108624468950438313186168670654296875
>> You're going to have to file a lot of bugs.
>> On Mon, Mar 29, 2010 at 11:32 PM, Himanshu <g [dot] himanshu [at] gmail [dot] com> wrote:
>>>
>>> Thanks Daniel and David.. I just tried it on java also, results are
>>> exactly the same :)
>>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
>



--
@fedesilva

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
I think groovy uses bigdecimal by default.

Sent from my iPhone
On Mar 31, 2010, at 6:13 PM, James Iry <jamesiry [at] gmail [dot] com> wrote:

Nope. Your string is just being truncated
irb(main):014:0> "%.55f" % (0.4 * 0.4)=> "0.1600000000000000310862446895043831318616867065429687500"

On Wed, Mar 31, 2010 at 2:35 PM, Federico Silva <fede [dot] silva [at] gmail [dot] com (fede [dot] silva [at] gmail [dot] com" rel="nofollow">fede [dot] silva [at] gmail [dot] com)> wrote:
On Tue, Mar 30, 2010 at 16:14, Daniel Sobral <dcsobral [at] gmail [dot] com (dcsobral [at] gmail [dot] com" rel="nofollow">dcsobral [at] gmail [dot] com)> wrote:
> I know ABC uses bigdecimal by default (and who here ever heard of it? :). I
> think Ruby

yep

$ irb
>> 0.4*0.4
=> 0.16
>>


> and TCL might do it too, not sure.
>
> On Tue, Mar 30, 2010 at 11:48 AM, James Iry <jamesiry [at] gmail [dot] com (jamesiry [at] gmail [dot] com" rel="nofollow">jamesiry [at] gmail [dot] com)> wrote:
>>
>> Here it is in GHC Haskell
>> Prelude> 0.4 * 0.4
>> 0.16000000000000003
>> And Python
>> >>> 0.4 * 0.4
>> 0.16000000000000003
>> And gcc C++
>> #include <iostream>
>> #include <iomanip>
>> using namespace std;
>> int main(int argc, char** argv) {
>>       cout << setprecision(55) << 0.4 * 0.4 << endl;
>> }
>> 0.16000000000000003108624468950438313186168670654296875
>> You're going to have to file a lot of bugs.
>> On Mon, Mar 29, 2010 at 11:32 PM, Himanshu <g [dot] himanshu [at] gmail [dot] com (g [dot] himanshu [at] gmail [dot] com" rel="nofollow">g [dot] himanshu [at] gmail [dot] com)> wrote:
>>>
>>> Thanks Daniel and David.. I just tried it on java also, results are
>>> exactly the same :)
>>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
>



--
@fedesilva

James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
Ding ding ding!  A winner!
groovy:000> 0.4 * 0.4===> 0.16groovy:000> 0.4 * 0.4 == 0.16===> truegroovy:000> (0.4 * 0.4).getClass() ===> class java.math.BigDecimal

On Wed, Mar 31, 2010 at 3:31 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
I think groovy uses bigdecimal by default.

Sent from my iPhone
On Mar 31, 2010, at 6:13 PM, James Iry <jamesiry [at] gmail [dot] com> wrote:

Nope. Your string is just being truncated
irb(main):014:0> "%.55f" % (0.4 * 0.4)=> "0.1600000000000000310862446895043831318616867065429687500"

On Wed, Mar 31, 2010 at 2:35 PM, Federico Silva <fede [dot] silva [at] gmail [dot] comfede [dot] silva [at] gmail [dot] com> wrote:
On Tue, Mar 30, 2010 at 16:14, Daniel Sobral <dcsobral [at] gmail [dot] comdcsobral [at] gmail [dot] com> wrote:
> I know ABC uses bigdecimal by default (and who here ever heard of it? :). I
> think Ruby

yep

$ irb
>> 0.4*0.4
=> 0.16
>>


> and TCL might do it too, not sure.
>
> On Tue, Mar 30, 2010 at 11:48 AM, James Iry <jamesiry [at] gmail [dot] comjamesiry [at] gmail [dot] com> wrote:
>>
>> Here it is in GHC Haskell
>> Prelude> 0.4 * 0.4
>> 0.16000000000000003
>> And Python
>> >>> 0.4 * 0.4
>> 0.16000000000000003
>> And gcc C++
>> #include <iostream>
>> #include <iomanip>
>> using namespace std;
>> int main(int argc, char** argv) {
>>       cout << setprecision(55) << 0.4 * 0.4 << endl;
>> }
>> 0.16000000000000003108624468950438313186168670654296875
>> You're going to have to file a lot of bugs.
>> On Mon, Mar 29, 2010 at 11:32 PM, Himanshu <g [dot] himanshu [at] gmail [dot] comg [dot] himanshu [at] gmail [dot] com> wrote:
>>>
>>> Thanks Daniel and David.. I just tried it on java also, results are
>>> exactly the same :)
>>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
>



--
@fedesilva


Dave Smith
Joined: 2010-04-05,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
Sure, it's a winner, although a fair bit slower than native floating-point which is calculated by hardware routines as oppose to software.

Almost all hardware that we use today implements IEEE 754 (http://en.wikipedia.org/wiki/IEEE_754-1985),  which is a binary floating-point mechanism, which handles binary fractions well (2 to the power of minus n).  These fractions are 1/2, 1/4, 1/8, 1/16, etc.  Unfortunately,  we naturally use fractions that are decimals (10 to the power of minus n).  These fractions are 1/10, 1/100, 1/1000, 1/10000, etc.  We are quite aware that many real number can't be represented in our decimal system exactly (1/3 for example), but it comes as a surprise to us that using a binary system cannot represent 0.1 exactly. The decimal value 0.1 is represented in binary as 0.0001100110011, where the 0011 bits repeat forever.  This evaluates as follows:

0.1 ~=  1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 == 0.099609375

(The machine will further translate this to the IEEE 754 standard, so it will be represented differently in memory)


There is a recent update to the IEEE 754 standard (http://en.wikipedia.org/wiki/IEEE_754-2008), which provides for decimal number representations and decimal arithmetic.  There are software package in C/C++ that provide this standard, but it will likely be some time (if ever) before we see native hardware implementation from Intel.

I'm not sure how BigDecimal works.  By the name, I would assume it implements decimal floating-point arithmetic in software.


--DS


On 31 March 2010 18:45, James Iry <jamesiry [at] gmail [dot] com> wrote:
Ding ding ding!  A winner!
groovy:000> 0.4 * 0.4===> 0.16groovy:000> 0.4 * 0.4 == 0.16===> truegroovy:000> (0.4 * 0.4).getClass() ===> class java.math.BigDecimal

On Wed, Mar 31, 2010 at 3:31 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
I think groovy uses bigdecimal by default.

Sent from my iPhone
On Mar 31, 2010, at 6:13 PM, James Iry <jamesiry [at] gmail [dot] com> wrote:

Nope. Your string is just being truncated
irb(main):014:0> "%.55f" % (0.4 * 0.4)=> "0.1600000000000000310862446895043831318616867065429687500"

On Wed, Mar 31, 2010 at 2:35 PM, Federico Silva <fede [dot] silva [at] gmail [dot] comfede [dot] silva [at] gmail [dot] com> wrote:
On Tue, Mar 30, 2010 at 16:14, Daniel Sobral <dcsobral [at] gmail [dot] comdcsobral [at] gmail [dot] com> wrote:
> I know ABC uses bigdecimal by default (and who here ever heard of it? :). I
> think Ruby

yep

$ irb
>> 0.4*0.4
=> 0.16
>>


> and TCL might do it too, not sure.
>
> On Tue, Mar 30, 2010 at 11:48 AM, James Iry <jamesiry [at] gmail [dot] comjamesiry [at] gmail [dot] com> wrote:
>>
>> Here it is in GHC Haskell
>> Prelude> 0.4 * 0.4
>> 0.16000000000000003
>> And Python
>> >>> 0.4 * 0.4
>> 0.16000000000000003
>> And gcc C++
>> #include <iostream>
>> #include <iomanip>
>> using namespace std;
>> int main(int argc, char** argv) {
>>       cout << setprecision(55) << 0.4 * 0.4 << endl;
>> }
>> 0.16000000000000003108624468950438313186168670654296875
>> You're going to have to file a lot of bugs.
>> On Mon, Mar 29, 2010 at 11:32 PM, Himanshu <g [dot] himanshu [at] gmail [dot] comg [dot] himanshu [at] gmail [dot] com> wrote:
>>>
>>> Thanks Daniel and David.. I just tried it on java also, results are
>>> exactly the same :)
>>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
>



--
@fedesilva



James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
It's not decimal floating point.  Unlike a floating point number which has a fixed number of bits, BigDecimal is a bignum meaning the size of possible numbers is limited only by memory (or other similar JVM limitations like object handles). And frankly, if we're going to pay that price, I'd rather have a BigRational (a pair of BigInts) than BigDecimal which can't even represent 1/3 exactly.

On Mon, Apr 5, 2010 at 9:31 AM, Dave Smith <dave.smith.to@gmail.com> wrote:


I'm not sure how BigDecimal works.  By the name, I would assume it implements decimal floating-point arithmetic in software.


bmaso
Joined: 2009-10-04,
User offline. Last seen 2 years 40 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)

Well, of course for any rational "base" representation there are
numbers that can't be represented. That is, if you're going to
represent numbers as

... + a1*b^x + a2*b^(x+1) + a3*b^(x+2) + ...

(where the a's and x are integers)

then any number with a prime root that is not shared with the prime
roots of b is not representable.

Clojure uses a Ratio class for arbitrary-precision math -- which I
think is probably the same concept as James' "BigRational" -- just two
BigIntegers: numerator and denominator. Weird performance
characteristics though, since addition can be way more expensive than
multiplication with Ratios.

Best regards,
Brian Maso
(949) 395-8551
brian [at] blumenfeld-maso [dot] com
twitter: @bmaso
skype: brian.maso
LinkedIn: http://www.linkedin.com/in/brianmaso

On Mon, Apr 5, 2010 at 10:26 AM, James Iry wrote:
> It's not decimal floating point.  Unlike a floating point number which has a
> fixed number of bits, BigDecimal is a bignum meaning the size of possible
> numbers is limited only by memory (or other similar JVM limitations like
> object handles). And frankly, if we're going to pay that price, I'd rather
> have a BigRational (a pair of BigInts) than BigDecimal which can't even
> represent 1/3 exactly.
>
> On Mon, Apr 5, 2010 at 9:31 AM, Dave Smith wrote:
>>
>>
>> I'm not sure how BigDecimal works.  By the name, I would assume it
>> implements decimal floating-point arithmetic in software.
>>
>
>

Dave Smith
Joined: 2010-04-05,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
Thanks for the info.

And I agree, rationals are another interesting option.  I don't know about BigInts, but you can get really great performance using a Rational class with primitive ints.   I understand there is an example in the "Programming in Scala" book.

Imho,  in most applications that require fractional arithmetic, the BigDecimal is a bit of an overkill.  Most application that do arithmetic fall into two categories:  financial applications, and statistical/scientific applications. 

Statistical and scientific application are well suited to native binary floating-point because they tend to require massively-iterative calculations.  Hardware floating-point calculations are faster than software floating or fixed calculations, and they are accurate (they just don't have predictable rounding).  They may require extremely large or extremely small values,  but double precision floating-points  (10^-308 to 10^308), with accuracy to 16 decimal digits are usually more than enough.

Financial applications do not require "Big" anything.  In most world currencies, values between 10^-12 and 10^12 are as accurate as you need to get.  For these applications, one should be concerned with predictable evaluation after rounding.  What that means is calculations preserve as many "decimal" digits as possible between calculations, and that rounding is done in a way the preserves decimal digits.  Beyond this, performance is the only concern.  Seems to me that a Rational number implementation with primitive integers would fit the bill.




--DS


On 5 April 2010 13:26, James Iry <jamesiry [at] gmail [dot] com> wrote:
g point number which has a fixed number of bits, BigDecimal is a bignum meaning the size of possible numbers is limited only by memory (or other similar JVM limitations like object handles). And frankly, if we're going to pay that price, I'd rather have a BigRational (a pair of BigInts) than BigDecimal which can't even represent 1/3 exactly.

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
On Mon, Apr 5, 2010 at 1:45 PM, Brian Maso <brian [at] blumenfeld-maso [dot] com> wrote:
Clojure uses a Ratio class for arbitrary-precision math -- which I
think is probably the same concept as James' "BigRational" -- just two
BigIntegers: numerator and denominator. Weird performance
characteristics though, since addition can be way more expensive than
multiplication with Ratios.
It cannot help but be more expensive because
  a/b + c/d = (a*d + b*c) / b*d
(three multiplications and one addition), while
  a/b * c/d = a*c / (b*d)
(two multiplications, no addition).

Also, if they store things in reduced form, they can compute gcd(a,d) and gcd(b,c) for multiplication--which is on smaller numbers--while in the latter case, they have to finish the entire computation and then do gcd(a*d+b*c , b*d).  gcd algorithms are pretty slow, and are definitely superlinear, so the latter computation is a lot more work.

  --Rex
 
Ruslan Shevchenko
Joined: 2009-07-07,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)

> Financial applications do not require "Big" anything. In most world
> currencies, values between 10^-12 and 10^12 are as accurate as you need to
> get. For these applications, one should be concerned with predictable
> evaluation after rounding. What that means is calculations preserve as
> many
> "decimal" digits as possible between calculations, and that rounding is
> done
> in a way the preserves decimal digits. Beyond this, performance is the
> only
> concern.

In reality, floating point arithmetic have some issues, which force use
decimal arithmetic in finance domain.

See http://speleotrove.com/decimal/decifaq1.html#inexact

>
>
>
> --DS
>
>
> On 5 April 2010 13:26, James Iry wrote:
>
>> g point number which has a fixed number of bits, BigDecimal is a bignum
>> meaning the size of possible numbers is limited only by memory (or other
>> similar JVM limitations like object handles). And frankly, if we're
>> going to
>> pay that price, I'd rather have a BigRational (a pair of BigInts) than
>> BigDecimal which can't even represent 1/3 exactly.
>

Dave Smith
Joined: 2010-04-05,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)

This was exactly the point I was making -- "we should not use binary floating point for financial" (and I have read speleotrove extensively in the past).  If you go back and read the thread carefully, we are discussing the merits of decimal vs rationals as an alternative.  

--DS


2010/4/5 Ruslan Shevchenko <rssh [at] gradsoft [dot] com [dot] ua>
floating point arithmetic have some issues, which force use
decimal arithmetic in financ

Ruslan Shevchenko
Joined: 2009-07-07,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)

> This was exactly the point I was making -- "we should not use binary
> floating point for financial" (and I have read speleotrove extensively in
> the past). If you go back and read the thread carefully, we are
> discussing
> the merits of decimal vs rationals as an alternative.
>

Ok, may be I miss something.

Note, that mathematically precise figures (such as rationals) in some
situations will be incorrect from accounting point of view.
//for example you can't have exactly 100/3 euros on you bank account
(It's because accounting rules have been formed before computers)

So, for storing numbers using decimal is more natural. For calculations,
using rational arithmetic is possible, but in some cases we need emulate
accounting rules (such as banker's rounding) which are not very natural
for rational arithmetic.

> --DS
>
>
> 2010/4/5 Ruslan Shevchenko
>
>> floating point arithmetic have some issues, which force use
>> decimal arithmetic in financ
>>
>

Dave Smith
Joined: 2010-04-05,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
Historically,  the currencies that were derived from the Spanish Dollar (US Dollar, Canadian Dollar, Mexican Peso, Chinese Yuan, etc.) were better suited to binary representation than those currencies today.  The Spanish dollar coin was worth 8 Spanish Reals, and was commonly known as "a piece of eight".   Although the US Dollar was decimalized from it's creation, it was still common to do business in eights of a dollar throughout the Americas.  In fact, right up until 2001, the NYSE valued stock in eighths of a dollar.

In hindsight, if we still used 8'ths, we wouldn't have any problems today with computer rounding errors like the ones we are discussing today.


I would disagree with you in your statement that accounting arithmetic is in some way not natural for rational arithmetic.   Indeed all accounting values are rational, and I know of no accounting practice that make use of irrational number (such as pi or e).

If I'm wrong please clarify.


--DS


2010/4/5 Ruslan Shevchenko <rssh [at] gradsoft [dot] com [dot] ua>
g numbers using decimal is more natural. For calculations,
using rational arithmetic is possible, but in some cases we need emulate
accounting rules (such as banker's rounding) which are not very natural
for rational

Dave Smith
Joined: 2010-04-05,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
Now that I think about it, perhaps you are right that if we do multiple operations in rational form before rounding,  the end result could be different than if we do that same operations in decimal form, rounding after each operation, as an accountant would do.

Good point!

--DS


2010/4/5 Ruslan Shevchenko <rssh [at] gradsoft [dot] com [dot] ua>
> This was exactly the point I was making -- "we should not use binary
> floating point for financial" (and I have read speleotrove extensively in
> the past).  If you go back and read the thread carefully, we are
> discussing
> the merits of decimal vs rationals as an alternative.
>

Ok, may be I miss something.

Note, that mathematically precise figures (such as rationals) in some
situations will be incorrect from accounting point of view.
//for example you can't have exactly 100/3 euros on you bank account
(It's because accounting rules have been formed before computers)

So, for storing numbers using decimal is more natural. For calculations,
using rational arithmetic is possible, but in some cases we need emulate
accounting rules (such as banker's rounding) which are not very natural
for rational arithmetic.



> --DS
>
>
> 2010/4/5 Ruslan Shevchenko <rssh [at] gradsoft [dot] com [dot] ua>
>
>> floating point arithmetic have some issues, which force use
>> decimal arithmetic in financ
>>
>



Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: 0.4 * 0.4 is not 0.16, why? (is this a bug?)
Interesting! How far back in time does the the Spanish dollar go? There is mention of currency divisible by eight in the Talmud about 2 millennia ago.

On Mon, Apr 5, 2010 at 10:56 PM, Dave Smith <dave.smith.to@gmail.com> wrote:
Historically,  the currencies that were derived from the Spanish Dollar (US Dollar, Canadian Dollar, Mexican Peso, Chinese Yuan, etc.) were better suited to binary representation than those currencies today.  The Spanish dollar coin was worth 8 Spanish Reals, and was commonly known as "a piece of eight".   Although the US Dollar was decimalized from it's creation, it was still common to do business in eights of a dollar throughout the Americas.  In fact, right up until 2001, the NYSE valued stock in eighths of a dollar.

In hindsight, if we still used 8'ths, we wouldn't have any problems today with computer rounding errors like the ones we are discussing today.


I would disagree with you in your statement that accounting arithmetic is in some way not natural for rational arithmetic.   Indeed all accounting values are rational, and I know of no accounting practice that make use of irrational number (such as pi or e).

If I'm wrong please clarify.


--DS


2010/4/5 Ruslan Shevchenko <rssh [at] gradsoft [dot] com [dot] ua>
g numbers using decimal is more natural. For calculations,
using rational arithmetic is possible, but in some cases we need emulate
accounting rules (such as banker's rounding) which are not very natural
for rational


Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland