Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to count from 0.0001 to 1 in ruby?

I want to count from 0.0001 to 1 with 0.0001 steps in ruby. I wrote this code but it enters to an infinite loop. Somewhy the interpreter does a wrong summation.

x = 0.0001
while x != 1.0
  puts x
  x = x + 0.0001
end

Here is the first 10 value it gives:

0.0001
0.0002
0.00030000000000000003
0.0004
0.0005
0.0006000000000000001
0.0007000000000000001
0.0008000000000000001
0.0009000000000000002
0.0010000000000000002

It should be 0.0001, 0.0002, 0.0003, etc... How can I make it working? Thanks!

like image 291
Hiddin Avatar asked Dec 16 '11 14:12

Hiddin


3 Answers

Try this:

0.0001.step(1, 0.0001).each { |i| puts i }

EDIT: you should use the Float#step method because it shields you from the weirdness of float arithmetic. Float#step will take care of incrementing the value and comparing to the limit in a float-proof way. For more information have a look at the official documentation of Float#step.

like image 133
gioele Avatar answered Nov 18 '22 07:11

gioele


The problem is that real numbers in ruby are not represented exactly due to binary storage and manipulation. I would do this

x = 1
while x < 10000
    puts (x/10000).round(4)
    x += 1
end
like image 21
ghoppe Avatar answered Nov 18 '22 06:11

ghoppe


Rather than x != 1.0, put x < 1.0. That will at least be sure your loop ends.

A binary system like those that run all of our modern computers cannot (easily) represent fractions, especially ones that cannot be accurately represented in decimal. That is where the strange number comes in when you should have .0003. It is an artifact of how the numbers are represented internally.

Some languages are better at dealing with numbers and accuracy than others, so if the accuracy of the numbers matters, you either need to use a different language, use a library that handles the number things for you (significant digits and all that), or you need to handle it yourself with appropriate rounding, etc. at each step.

like image 1
cdeszaq Avatar answered Nov 18 '22 07:11

cdeszaq