Ruby - Converting Small Float Numbers to String

140 views Asked by At

I've noticed that small number floats, like 0.00000000345 end up getting converted to scientific notation, ie, 3.45e-9. This makes sense, but it looks like if I convert the float to a string (as I'd like to manipulate specific elements of the float according to its contents), the string itself adopts this notation.

Since it's now a string, it's easy enough to "translate" the contents back to a proper decimal number and manipulate it, but I was wondering if there is a built-in way that automatically allows for the saving of the actual decimal number as a string, rather than the scientific notation. Might not be, and I don't see anything in the documentation, but it can't hurt to ask.

2

There are 2 answers

0
Stefan On BEST ANSWER

With a round-trip to BigDecimal you can use its to_s method which allows the output format to be explicitly specified:

require 'bigdecimal'
require 'bigdecimal/util'

float = 0.00000000345
#=> 3.45e-09

float.to_d.to_s('F')
#=> "0.00000000345"

Note that Float#to_d attempts to determine the precision automatically which might fail for certain numbers:

float = 1.0.next_float
#=> 1.0000000000000002

float.to_d.to_s('F')
#=> "1.0"

Here, it might help to convert the float to a string in advance: (you also don't need to require bigdecimal/util using this variant)

BigDecimal(float.to_s).to_s('F')
#=> "1.0000000000000002"

Keep in mind that those outputs don't show the float's actual value. The exact decimal value for 0.00000000345 as a double-precision floating point number is:

0.000000003449999999999999873659487851216588760738801511251949705183506011962890625
2
Rajagopalan On

Use sprintf

small_number = 0.00000000345
formatted_string = sprintf("%.10f", small_number)    
p formatted_string

Output

"0.0000000034"

In this example, "%.10f" is a format specification for the sprintf function. The %f specifies that the argument should be formatted as a floating-point number, and .10 specifies that the number should be represented with 10 digits after the decimal point.