How to count from 0.0001 to 1 in ruby?

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

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

Here is the first meaning 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 work? Thanks!

+7
source share
6 answers

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

 x = 1 while x < 10000 puts (x/10000).round(4) x += 1 end 
+2
source

Try the following:

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

EDIT : You should use the Float#step method because it protects you from the weirdness of float arithmetic. Float#step will take care of increasing the value and comparing it with the limit using the floating point method. See the official Float#step documentation for more information.

+16
source

Instead of x != 1.0 put x < 1.0 . This, at least, will definitely end your loop.

A binary system, such as those that run all of our modern computers, cannot (easily) represent fractions, especially those that cannot be accurately represented in decimal form. This is where a weird number comes in when you should have .0003 . This is an artifact of how numbers are represented internally.

Some languages ​​do better with numbers and accuracy than others, so if the accuracy of numbers matters, you either need to use a different language or use a library that handles the number of things for you (meaningful numbers and all that), or you need to handle it independently with appropriate rounding, etc. at every step.

+1
source

Floating-point numbers are not exactly accurate . Wikipedia article on floating-point .

If you must have pure x, I would recommend using an integer and dividing down by 1000 before using the value. If you do not care about small noises, you will be fine with changing your time, until x! = 1.0, while x <1.0

0
source

What you see is related to the binary representation of floating point numbers. This affects all programming languages. For more information, see What Every Computer Scientist Should Know About Floating-Point Arithmetic .

What you can do is round it to the appropriate number of digits during printing, or, as goiele found, use step :

 0.0001.step(1, 0.0001).each do |i| puts i end 
0
source
 1.step(10000, 1).each { |x| puts "%f" % (x / 10000.0).round(4) } 
0
source

All Articles