rubyでfloatを整数ならintに変換したい。例えば
a = 1.0
b = 2.5
a.to_int_if_whole # => 1
b.to_int_if_whole # => 2.5
基本的に、小数点のない数値に「.0」を表示しないようにしています。エレガントな(または組み込みの)方法を探しています
def to_int_if_whole(float)
(float % 1 == 0) ? float.to_i : float
end
rubyでfloatを整数ならintに変換したい。例えば
a = 1.0
b = 2.5
a.to_int_if_whole # => 1
b.to_int_if_whole # => 2.5
基本的に、小数点のない数値に「.0」を表示しないようにしています。エレガントな(または組み込みの)方法を探しています
def to_int_if_whole(float)
(float % 1 == 0) ? float.to_i : float
end
それへの簡単な方法の1つは次のとおりです。
class Float
def prettify
to_i == self ? to_i : self
end
end
その理由は次のとおりです。
irb> 1.0 == 1
=> true
irb> 1 == 1.0
=> true
次に、次のことができます。
irb> 1.0.prettify
=> 1
irb> 1.5.prettify
=> 1.5
ワンライナースプリント...
sprintf("%g", 5.0)
=> "5"
sprintf("%g", 5.5)
=> "5.5"
これは、私が望むように機能するようになったソリューションです。
class Float
alias_method(:original_to_s, :to_s) unless method_defined?(:original_to_s)
def is_whole?
self % 1 == 0
end
def to_s
self.is_whole? ? self.to_i.to_s : self.original_to_s
end
end
このようにis_whole?
して、必要に応じてロジックを更新できます (tadman のロジックが最も洗練されているようです)。これにより、Float が文字列に出力される場所 (たとえば、フォーム内) で、希望どおりに表示されることが保証されます (つまり、no最後にゼロ)。
皆さんのアイデアに感謝します。本当に役に立ちました。
Rubyについてはよくわかりません。
しかし、これは表示の問題です。使用しているライブラリに、数値を文字列に変換するときに数値をフォーマットする方法がない場合、私は非常に驚かれることでしょう。
あなたが望むものを正確に実行する包括的な書式設定オプションはないかもしれませんが、float が整数の float 表現である場合は true を返し、そうでない場合は false を返すメソッドを設定できます。作成した書式設定ルーチン内で (これを 1 か所で行うだけで済みます)、これが true か false かに基づいて書式設定を変更するだけです。
ここでは、数値を表示するときに小数点以下の桁数を制御する方法について説明します。
浮動小数点表現の複雑さに注意してください。数学は答えが 3 だと言うかもしれませんが、3.00000000000000000001 になるかもしれません。デルタを使用して、数値がほぼ整数であるかどうかを確認することをお勧めします。
Rails を使用している場合は、次のようnumber_to_rounded
にオプションstrip_insignificant_zeros
でヘルパーを使用できます。
ActiveSupport::NumberHelper.number_to_rounded(42.0, strip_insignificant_zeros: true)
またはこのように:
42.0.to_s(:rounded, strip_insignificant_zeros: true)
私は上記の投稿に同意する傾向がありますが、これを行う必要がある場合:
(float == float.floor) ? float.to_i : float
これが教育目的で提供された私の恐ろしくハックな実装です:
class Float
def to_int_if_whole(precision = 2)
("%.#{precision}f" % self).split(/\./).last == '0' * precision and self.to_i or self
end
end
puts 1.0.to_int_if_whole # => 1
puts 2.5.to_int_if_whole # => 2.5
puts 1.9999999999999999999923.to_int_if_whole # => 2
sprintfスタイルの呼び出しを使用する理由は、Float#roundメソッドよりもはるかに確実に浮動小数点近似を処理するためです。
Rubyについてもよくわかりません。
しかし、C++ では、次のようにします。
bool IsWholeNumber( float f )
{
const float delta = 0.0001;
int i = (int) f;
return (f - (float)i) < delta;
}
そして、それに基づいて出力精度をフォーマットします。