@sean: "Doing this:
raise "false" if ((625.91 + 900.00 + 22.00) != 1547.91)
..raises the exception.
Seems like a pretty major addition bug to me.  Anyone know of a good 
workaround?
	Sean O'Dell"
    @sean: "<quote>
Well known?  I had no idea this bug existed until I wrote a line of code that 
double-checked the arithmetic from a different app.  I have code all over 
doing simple arithmetic like this.  Ruby can't add 3 simple numbers?  I don't 
mean to be disproportionately negative, but that shakes my faith more than a 
little.  It's just simple arithmetic.  How old is this bug?  When is it 
getting fixed?
	Sean O'Dell"
    @jim: "<quote>
Sorry, to shake your faith, but consider the following:
  jfn@juno 124 /home/jfn/tmp > cat n.c
  int main()
  {
    printf("%.24f\n", 625.91+900.00+22.00);
  }
  jfn@juno 125 /home/jfn/tmp > ./a.out
  1547.909999999999854480847716
You might want to try the rational library.
Jim
Jim Freeze
Police:	Good evening, are you the host?
Host:	No.
Police:	We've been getting complaints about this party.
Host:	About the drugs?
Police:	No.
Host:	About the guns, then?  Is somebody complaining about the guns?
Police:	No, the noise.
Host:	Oh, the noise.  Well that makes sense because there are no guns
	or drugs here.  (An enormous explosion is heard in the
	background.)  Or fireworks.  Who's complaining about the noise?
	The neighbors?
Police:	No, the neighbors fled inland hours ago.  Most of the recent
	complaints have come from Pittsburgh.  Do you think you could
	ask the host to quiet things down?
Host:	No Problem.  (At this point, a Volkswagon bug with primitive
	religious symbols drawn on the doors emerges from the living
	room and roars down the hall, past the police and onto the
	lawn, where it smashes into a tree.  Eight guests tumble out
	onto the grass, moaning.)  See?  Things are starting to wind
	down."
    @decoux: "<quote>
S> Well known?  I had no idea this bug existed until I wrote a line of code that 
S> double-checked the arithmetic from a different app.  I have code all over 
S> doing simple arithmetic like this.  Ruby can't add 3 simple numbers?  I don't 
S> mean to be disproportionately negative, but that shakes my faith more than a 
S> little.  It's just simple arithmetic.  How old is this bug?  When is it 
S> getting fixed?
   <url>
Guy Decoux"
    @dave: "<quote>
It's about 40 years old, and unlikely to be fixed. Floating point 
numbers are not represented exactly inside computers, and so floating 
point comparisons are routinely deprecated in books on programming.  
Certain values cannot ever be expressed in floating point 
representation.
If you want exact, fractional, math, you should probably use the 
'rational' library and investigate 'mathn'.
Cheers
Dave"
    @sean: "<quote>
I don't expect a script language to have those same rounding problems, so I 
hope this gets fixed quickly.  Thanks for the tip.
	Sean O'Dell"
    @mneumann: "<quote>
Try the same in Python. It's the same. 
In Ruby you can use BigDecimal:
  require 'bigdecimal'
  BigDecimal.new("625.91") + 900 + 22 == BigDecimal.new("1547.91") # => true
Regards,
  Michael"
    @jgb3: "<quote>
For what its worth, it appears (on my box, at least) that perl and 
python both give the same result. It is not a Ruby bug, but rather a 
problem with floating point round off.
Jamis Buck
<email_address>
<url>
ruby -h | ruby -e 
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a << 
r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'"
    @sean: "<quote>
Funny though, if I set a variable to 1547.91 exactly, it is represented just 
fine.  A value during the arithmetic must be a value which can't be 
represented.
I had to massage my floating point math in C/C++ a lot many years ago, but I 
always assumed it was a flaw in the MS compiler, and once I got in the habit 
of doing it, I forgot about it.
Thanks for the info.  I'm far less bitter now about having to round the 
numbers for comparison.  =)
	Sean O'Dell"
    @ahoward: "<quote>
i'd say no time soon unless ruby decides to implement it's own floating point
hardware emulator:
  ~ > cat a.c
  #include <stdlib.h>
  #include <stdio.h>
  int
  main (argc, argv, env)
       int argc;
       char **argv;
       char **env;
  {
    float total = 1547.91;
    float a = 625.91;
    float b = 900.00;
    float c = 22.00;
    float sum;
    sum = a + b + c;
    fprintf (stdout, "total <%f>\n", total);
    fprintf (stdout, "sum <%f>\n", sum);
    return 0;
  }
  ~ > gcc a.c -o a
  ~ > ./a
  total <1547.910034>
  sum <1547.909912>
-a
===============================================================================
| EMAIL   888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4 Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4 918.565.0734
| ADDRESS 888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4 E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL     888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4 <url>
| TRY     888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4 for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done 
==============================================================================="
    @ljz: ""Sean O'Dell" <email_address> writes:
<quote>
In 1969 I took a course called Introduction to Computer Programming.  In
one of the early chapters of the textbook, we learned about a concept
called "floating point arithmetic".  One aspect of this topic that was
drilled into us is the way that floating point arithmetic does not yield
exact results.
I want to add that this concept, which is so basic to the understanding
of programming that it was taught in an introductory course before we
even wrote a line of code, was old information even in 1969.
This basic concept of floating point arithmetic is every bit as
pertinent today as it was in 1969 and the years prior to that.  Did you
actually not learn this concept before starting to program in Ruby?
In the off chance that you were absent that day when they talked about
this in school, or that the 5 pages that discussed this in your
Introduction to Computer Programming book accidentally got eaten by your
dog, I want you to know that the case that you are describing here is
_not_ a bug, but rather, an intrisic feature of how computers do certain
kinds of arithmetic.
Do a search in Google on "floating point arithmetic" (best to put
that entire phrase in double quotes) for more information.
 Lloyd Zusman
 <email_address>
 God bless you."
    @ljz: ""Sean O'Dell" <email_address> writes:
<quote>
Even the value 1547.91 might not be stored exactly as that value in its
internal floating point representation.  Doing the arithmentic isn't the
only way that "exact" values to become inexact.  Even the mere storing
the number internally in a floating point value might cause it it lose
accuracy.  Doing arithmetic simply causes these errors to accumulate,
and therefore be more likely to occur in a result.
For example, this number looks exact, but actually, it's an infinitely
repeating fraction in binary: 0.1
This is true for many "exact" values.
Therefore, you will lose accuracy simply by referencing many decimal
numbers in floating point.
You have a basic misunderstanding of floating point math if you consider
its rounding and truncation characteristics to be a compiler bug.
As other people have mentioned, there is a BigDecimal class in Ruby
that behaves closer to the way that you want.
Also, consider this: if you always want the computer to give you exact
results, what should these exact results be for each of the following
arithmetic evaluations? ...
  a = 1/3
  b = Math.atan2(1.0, 1.0)
  c = Math.sqrt(5)
How many decimal points should they go to.  Where should they round?
 Lloyd Zusman
 <email_address>
 God bless you."
    @sean: "<quote>
This is absolutely true; I've never taken any computer class, so I completely 
missed that basic information.
Now that I know what it is, I'm fine with returning to old behavior and just 
massaging my comparisons.
Well, this has an infinite decimal value even in plain math.  Everyone should 
expect his sort of rounding problem.  But the simple arithmetic rounding 
error is not something you would anticipate without, say, having a professor 
point your nose sue84@example.net.
Anyway, thanks for the info everyone,
	Sean O'Dell"
    @david: "<quote>
Don't use floats for financial figures. Use a Money object, such as the 
one[1] Fowler describes in PoEAA. That way you'll be setup for handling 
currency issues as well.
[1] <url>
David Heinemeier Hansson,
<url>       A No-Step-Three Wiki in Ruby
<url>    Web-based Project Management
<url>  Broadcasting Brain
<url>     Development & Consulting Services"
    @ljz: ""Sean O'Dell" <email_address> writes:
<quote>
One way that we were taught to do floating point comparisons is
to not check for equality, but rather, to check for the result
to be within a certain "delta" of the targeted value.  For example:
  target = 1547.91
  delta = 0.0005  # some suitably small (but not too small!) number
  result = 625.91 + 900.00 + 22.00
  if (result > target - delta && result < target + delta)
  ... etc. ...
That's true.  Most people find it counter-intuitive to think that values
like 0.1 are inexact in floating point.
Just as the fraction 1/3 is an infinite repeating decimal in base 10,
the fraction 1/10 is also an infinite repeating decimal in base 2
(binary).  It can also be shown that your number, 1547.91, is another
value that doesn't have an exact floating point representation.
I'm glad to help.  And please forgive my flippant reply in my earlier
message.  It just seemed appropriate in response to your somewhat
strident call to the Ruby community that we fix this floating point
"bug". :)
 Lloyd Zusman
 <email_address>
 God bless you."
    @discord: "<quote>
just a point here... floats are just one binary integer times two to 
the power of another binary integer:
   num = 0b11000001011111010001111010111000010100011110101110001 * 0b10 
** -0b101010
     ==>1547.91
   "%.43f"%num
     ==>"1547.9100000000000818545231595635414123535156250"
   "%.43f"%1547.91
     ==>"1547.9100000000000818545231595635414123535156250"
The BigDecimal class uses actual decimal numbers, IIRC. It might be 
more appropriate for a calculator app, or something like that. I 
suppose it is much slower, however.
rather than rounding, you might consider:
   (625.91 + 900.00 + 22.00) - 1547.91 > 0.0000000001
     ==>false
or even, for the scope of your app:
   class Float
     def ==(other)
       self - other < 0.000000000001
     end
   end
     ==>nil
   (625.91 + 900.00 + 22.00) == 1547.91
     ==>true
or, if you aren't into redefing #==, you might just make a method, say, 
#approx_eql?(other) for Float.
cheers,
Mark"
    @Mike: "<quote>
Financial calculations aren't done in floating point. There are various
number formats that are used, but they all boil down to some form of integer
arithmetic. For example, fixed point decimal may be used, where the value
$625.91 is represented as the integer 62591 with a scaling factor of two
decimal places. In other words, the arithmetic is actually done in pennies,
not dollars.
-Mike"
    @ljz: "<email_address> (Phil Tomson) writes:
<quote>
I have been programming for 35 years, and during this time, I keep
seeing members of the financial community writing programs that do money
math with floating point numbers.  Several times in my career we had to
rewrite code that mis-used floating point in this way, when people
finally realized that they can't get exact results.
One way around this in Ruby is to use the BigDecimal class.  It allows
arbitrary precision math to be performed.  There are other solutions, as
well.  For example, the Rational class can also be used for financial
calculations.
 Lloyd Zusman
 <email_address>
 God bless you."
    @hal9000: "<quote>
Offhand I'd say this bug dates back to the 1940s, and isn't
getting fixed any time soon.
Seriously, I think it's a matter of trying to store an infinite
number of digits in a finite number of bits.
For a daily life example: How many digits does it take to store
"1/3" exactly?  0.333333...
Hal"
    @mkhan: "I guess, you guys are missing the point,
in real life you can't have exact answer of 1/3 + 2.3 + 1.3
but you can have exact answer of 625.91 + 900.00 + 22.00
Mohammad
- Original Message -
From: "Hal Fulton" <email_address>
To: "ruby-talk ML" <email_address>
Sent: Wednesday, May 12, 2004 3:15 PM
Subject: Re: Major Addition Bug?
<quote>
that
over
don't
than a"
    @aredridel: "<quote>
Short answer: use rational numbers  slower, but works.
Long answer: For finance, specifically, use integer numbers of pennies,
at least for US currency, or some other fixed-point format. It has
error, but it's an accepted, standard error.  According to most
accountants, 0.005 + 0.044 is 0.05. 
Ari"
    @hal9000: "<quote>
Only if you build a computer that works in decimal. In binary,
625.91 is as inexact as 1/3 is in decimal.
Hal"
    @guslist: "<quote>
Well, my HP48 calculator's processor is able to do math in binary or
decimal. The real numbers are stored in memory in decimal and the
operations by default made in decimal. It doesn't make my calculations
any more precise, but it made (some of) the rounding errors less
suprising.
But Ruby doesn't compile on my HP48 :(
Guillaume."
    @sean: "<quote>
It's great to get some validation on some of my ancient rounding problems.  It 
never occurred to me that the problem rested with a fundamental issue in the 
floating point processor.  I had always thought I was doing something wrong 
or the compiler was funky.
I've done a lot of financial stuff using long integers and pennies.  It's nice 
to hear that's a method others use, and recommend.
All: Don't worry about busting my chops.  It was earned.  I am just as likely 
to nail someone for their ignorance.  Live and learn.
Anyway, upside: this didn't cost me a dime in tuition and now I know.  =)  
Suckers!  j/k
	Sean O'Dell"
    @sean: "<quote>
Sort of makes me wonder if someone somewhere doesn't make a replacement FPU 
that does all of its calculations as real decimal values, or at least 
automatically corrects rounding errors.
	Sean O'Dell"
    @sean: "<quote>
I will go so far as to have a stern talk with Herbert C. Schildt for not 
mentioning the floating point issue in any of the many books I bought which 
were written by him, but I refuse to shoot him.
	Sean O'Dell"
    @StephanKaemper: "<quote>
SCNR, but:
irb(main):001:0> 1/3
=> 0
*That* result fits into a single bit. ;-)
But in general there's not much to add to this thread, but to summarize it:
- For financial calculations use specialised classes (which should
   handle different currencies, BTW)
- If you *need* a higher number of digits use BigDecim (which is
    documented in the 'Ruby Standard Library Documentation' available
    at <url> )
- Never, repeat *never* compare floats with == or other operators like
   that. Define some kind of accuracy, say epsilon and use a usual metric
   like this:
         ( a_value - something_else ).abs < epsilon
- Don't use == to compare floats and last but not least
- Comparing floats with == is a Bad Thing.
Well, that's it - more or less.
Happy rubying,
Stephan"
    @discord: "<quote>
Oh, but you can! you just need to choose an appropriate radix. Radix 30 
will do:
1/3 + 2.3 + 1.3 becomes:
0.a + 2.9 + 1.9 = 3.s
Your answer is 3.s radix 30. This translates to approximately 3.93333 
radix ten (decimal); or about 11.11101 radix 2 (binary).
In real life, number stay fractions. Decimal notation is only precise 
for numbers whose denominators factor out to twos and fives. Binary 
(and hence floating point arithmetic) is only precise for fractions 
whose denominator is factorable into twos. So unless your decimal 
number ends in .25, .125, and so on, you're out of luck.
Only when using base ten, which computers usually don't.
cheers,
Mark"
    @NOSPAM: "<quote>
Exactly. Has anyone ever tried to write 1.1 in binary? Tell me when you've
finished writing it ;-)
Use BigNums which are probably an implementation (I haven't looked into
Ruby's) of BCD or similar. BCD (Binary Coded Decimal) has been in use for
ages. It uses one byte per decimal digit. A less wasteful form is called
packed BCD and uses a nibble (4 bits) to store a decimal digit.
BCD is older than punch cards btw.
Another way out using floats is to redefine Float888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4==
$ irb
irb(main):001:0> class Float
irb(main):002:1>  def ==(other)
irb(main):003:2>   (self-other).abs<1E-7
irb(main):004:2>  end
irb(main):005:1> end
=> nil
irb(main):006:0> (625.91 + 900.00 + 22.00) == 1547.91
=> true
Hth"
    @ljz: ""Sean O'Dell" <email_address> writes:
<quote>
Well, the IBM mainframes from the 1960's had decimal arithmetic hardware
built in.  They could do fixed point (integer), floating point, and
decimal arithmetic via CPU instructions.
In fact, they even had several different internal formats for the
numbers used in decimal arithmetic.
COBOL and PL/I compilers from back then could use this CPU capability
directly for calculations.
Do more modern chunks of Big Iron still have built-in packed and zoned
decimal arithmetic hardware?
In any case, the machines that most of us are likely to use these days
have to do this kind of math in software only.
 Lloyd Zusman
 <email_address>
 God bless you."
    @ambrus: "<quote>
No. I'd rather think this is not the problem. The problem is
that you should not compare floating-point numbers with == or != unless you
have a good reason to do it. 
In this case, you should just do this:
raise "false" if ((625.91 + 900.00 + 22.00) - 1547.91).abs>1e-12
which just succeeds fine.  You don't usually need an infinite precision, and
in more complicated cases, you can't even acheive one.  (You could use
rationals here, because these are only simple arithmetic operations, and
you'd get an exact result."
    @discord: "<quote>
yeah, yeah... :) I realized when I read someone else's version of it 
that I had forgotten to take the absolute value. :/
Also, I hadn't thought of something else. Since it's a floating point 
number, you can't have a fixed epsilon for all comparisons. Very large 
numbers would always fail unless exactly equal, and very small numbers 
would always pass, even if very different.
So, epsilon should be generated from one of the floats you are 
comparing. That way, if you are comparing floats that are off in the 
1e200 or 1e-200 range, you will still get things right. Comparing 
(num1-num2).abs to num1*1e-8 will check that they are equal within 8 
significant digits.
   class Float
     def approx_eql?(other, epsilon=1e-8)
       epsilon *= self # fit epsilon to the number
       (self - other).abs < epsilon
     end
   end
This could be extended to allow either an epsilon, or an integer number 
of digits to check.
cheers,
Mark"
    @ambrus: "<quote>
No. Certainly not.
There are valid uses for ==, you just have to know the limits
of it on floating-point numbers if you are programming.  
Also, no programming language warns on it."
    @ambrus: "<quote>
Why not do interval arithmetics?  Of course, you can't implement that in pure
ruby, only as a C addition, as you'll have to do arithmetic in different
rounding modes.
ambrus"
{'source': 'USENET', 'other_information': '{"reply_count": 33, "forum_name": "comp.lang.ruby.20141021.mbox"}', 'file': 'data/output/usenet-comp.lang.parquet'}