Sprintf bug

J

jwesley

I think I've found a bug in the sprintf function:

D:\src\ruby>ruby -v
ruby 1.8.2 (2004-12-25) [i386-mswin32]

D:\src\ruby>irb
irb(main):001:0> sprintf("%.1f", 123456789012345678.to_f)
=> "123456789012345680.0"
irb(main):002:0> sprintf("%.1f", 123456789012345678.to_f).to_i
=> 123456789012345680

Notice that that sprintf changed the value by an order of magnitude...

Justin
 
J

Joel VanderWerf

jwesley said:
I think I've found a bug in the sprintf function:

D:\src\ruby>ruby -v
ruby 1.8.2 (2004-12-25) [i386-mswin32]

D:\src\ruby>irb
irb(main):001:0> sprintf("%.1f", 123456789012345678.to_f)
=> "123456789012345680.0"
irb(main):002:0> sprintf("%.1f", 123456789012345678.to_f).to_i
=> 123456789012345680

Notice that that sprintf changed the value by an order of magnitude...

Justin

FP imprecision changed the value by 2.0:

irb(main):008:0> orig = 123456789012345678
=> 123456789012345678
irb(main):009:0> sprintf("%.1f", orig.to_f).to_i - orig
=> 2

and:

irb(main):012:0> orig - 2.0 == orig
=> true
irb(main):013:0> orig + 2.0 == orig
=> true
irb(main):014:0> orig.to_f.to_i - orig
=> 2

It's not sprintf's fault.
 
D

Daniel Berger

jwesley said:
I think I've found a bug in the sprintf function:

D:\src\ruby>ruby -v
ruby 1.8.2 (2004-12-25) [i386-mswin32]

D:\src\ruby>irb
irb(main):001:0> sprintf("%.1f", 123456789012345678.to_f)
=> "123456789012345680.0"
irb(main):002:0> sprintf("%.1f", 123456789012345678.to_f).to_i
=> 123456789012345680

Notice that that sprintf changed the value by an order of magnitude...

Justin

Nope, not a Ruby bug:

/* Solaris 10 */
#include <stdio.h>

int main(){
printf("%.1f\n", 123456789012345678.0);
return 0;
}

djberge@~/programming/C-528>gcc -Wall -o printftest printftest.c
djberge@~/programming/C-529>./printftest
123456789012345680.0

Regards,

Dan
 
R

Rob Rypka

irb(main):001:0> sprintf("%.1f", 123456789012345678.to_f)
=3D> "123456789012345680.0"
irb(main):002:0> sprintf("%.1f", 123456789012345678.to_f).to_i
=3D> 123456789012345680

Two more helpless kittens, struck down before their prime.

Please think of the kittens.
 
N

nobu.nokada

Hi,

At Sat, 12 Nov 2005 07:32:13 +0900,
jwesley wrote in [ruby-talk:165361]:
Is there a standard way to get a more precise floating point number?

BigDecimal might help you.
 
M

Matthew Smillie

Is there a standard way to get a more precise floating point number?

Short answer. BigDecimal: http://www.ruby-doc.org/stdlib/libdoc/
bigdecimal/rdoc/index.html

Longer rambling answer and reason why it's not a bug in anything,
just a design choice: IEEE 754 double-precision (64-bit) floating
point numbers use 12 bits for sign and exponent, and 52 bits for the
significand. Therefore, the smallest integer that can't be exactly
represented as a float is 2^53+1

123456789012345678
9007199254740992 (2^53 + 1)

So the number used for the test is fairly obviously larger than that
value, and there's going to be some sort of error if you flip it
around and use it. Ferinstance:

irb(main):008:0> (2**53 + 1)
=> 9007199254740993
irb(main):009:0> (2**53 + 1).to_f.to_i
=> 9007199254740992

And look at *this* consequence of the inaccuracy:

irb(main):029:0> i = (2**53 - 1).to_f
=> 9.00719925474099e+15
irb(main):030:0> while i < (2**53 + 2)
irb(main):031:1> puts "#{i.to_i}"
irb(main):032:1> i += 1.0
irb(main):033:1> end
9007199254740991
9007199254740992
9007199254740992
9007199254740992
...

Fun stuff, eh?

It's also worth noting that depending on the hardware instruction,
you can get different results for the same calculation. And since we
don't program in assembly, you can get different results depending on
the compiler, or potentially compiler options, while still being
entirely consistent with the spec.

matthew smillie
 
G

gwtmp01

Short answer. BigDecimal: http://www.ruby-doc.org/stdlib/libdoc/
bigdecimal/rdoc/index.html

I'd recommended the following document if you really want to know
about floating point.
And if you haven't read this document (or something like it) then you
probably shouldn't
be writing programs (well, any *serious* programs) using floating point.

What Every Computer Scientist Should Know About Floating-Point
Arithmetic
http://docs.sun.com/source/806-3568/ncg_goldberg.html


Gary Wright
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Is this a bug? 7
Bug in sprintf? 23
sprintf bug (?) 8
cannot load watir 7
[BUG] IRB Segfault on Windows 0
Problem with Time.iso8601 4
Is this a bug or a whole new concept? 2
parentheses and newlines 2

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top