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
これは、私が望むように機能することになったソリューションです。
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が文字列に出力する場所(フォームなど)で、希望どおりに表示されるようになります。 to(つまり、最後にゼロがない)。
あなたのアイデアをみんなに感謝します-彼らは本当に助けてくれました。
それへの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"
Rubyについてはよくわかりません。
しかし、これはdisplayの問題です。使用しているライブラリに、数値を文字列に変換するときに数値をフォーマットする方法がない場合、私は非常に驚きます。
必要なことを正確に実行するキャッチオールフォーマットオプションがない場合もありますが、floatが整数のfloat表現である場合はtrueを返し、それ以外の場合はfalseを返すメソッドを設定できます。作成するフォーマットルーチン内で(したがって、これを1か所で行うだけで済みます)、これがtrueかfalseかに基づいてフォーマットを変更するだけです。
This は、数値を表示するときに小数点以下に表示される桁数を制御する方法について説明しています。
浮動小数点表現の複雑さに注意してください。数学は答えが3であると言うかもしれませんが、あなたは3.000000000000000000001を得るかもしれません。デルタを使用して、数値がほぼ整数であるかどうかを確認することをお勧めします。
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;
}
そして、それに基づいて出力精度をフォーマットします。