Techioz Blog

Ruby - 小さな浮動小数点数を文字列に変換する

概要

0.00000000345 のような小さな浮動小数点数は科学表記法、つまり 3.45e-9 に変換されてしまうことに気付きました。これは理にかなっていますが、float を文字列に変換すると (float の内容に従って float の特定の要素を操作したいため)、文字列自体がこの表記法を採用するように見えます。

これは文字列になっているので、内容を適切な 10 進数に「変換」して操作するのは簡単ですが、実際の 10 進数を自動的に保存できる組み込みの方法があるかどうか疑問に思っていました。科学的表記法ではなく、文字列です。そうではないかも知れませんし、ドキュメントには何も記載されていませんが、質問してみても損はありません。

解決策

BigDecimal へのラウンドトリップでは、出力形式を明示的に指定できる to_s メソッドを使用できます。

require 'bigdecimal'
require 'bigdecimal/util'

float = 0.00000000345
#=> 3.45e-09

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

Float#to_d は精度を自動的に決定しようとしますが、特定の数値では失敗する可能性があることに注意してください。

float = 1.0.next_float
#=> 1.0000000000000002

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

ここで、事前に浮動小数点を文字列に変換すると役立つ場合があります: (このバリアントを使用すると、bigdecmal/util を要求する必要もありません)

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

これらの出力には float の実際の値が表示されないことに注意してください。倍精度浮動小数点数としての 0.00000000345 の正確な 10 進数値は次のとおりです。

0.000000003449999999999999873659487851216588760738801511251949705183506011962890625