29

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
4

8 に答える 8

54

それへの簡単な方法の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
于 2009-07-03T03:23:06.333 に答える
50

ワンライナースプリント...

sprintf("%g", 5.0)
=> "5"

sprintf("%g", 5.5)
=> "5.5"
于 2011-03-04T12:05:44.603 に答える
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最後にゼロ)。

皆さんのアイデアに感謝します。本当に役に立ちました。

于 2009-07-07T17:36:42.697 に答える
3

Rubyについてはよくわかりません。

しかし、これは表示の問題です。使用しているライブラリに、数値を文字列に変換するときに数値をフォーマットする方法がない場合、私は非常に驚かれることでしょう。

あなたが望むものを正確に実行する包括的な書式設定オプションはないかもしれませんが、float が整数の float 表現である場合は true を返し、そうでない場合は false を返すメソッドを設定できます。作成した書式設定ルーチン内で (これを 1 か所で行うだけで済みます)、これが true か false かに基づいて書式設定を変更するだけです。

ここでは、数値を表示するときに小数点以下の桁数を制御する方法について説明します

浮動小数点表現の複雑さに注意してください。数学は答えが 3 だと言うかもしれませんが、3.00000000000000000001 になるかもしれません。デルタを使用して、数値がほぼ整数であるかどうかを確認することをお勧めします。

于 2009-07-03T00:52:10.283 に答える
3

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)
于 2015-04-13T10:03:05.017 に答える
2

私は上記の投稿に同意する傾向がありますが、これを行う必要がある場合:

(float == float.floor) ? float.to_i : float
于 2009-07-03T01:12:17.030 に答える
1

これが教育目的で提供された私の恐ろしくハックな実装です:

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メソッドよりもはるかに確実に浮動小数点近似を処理するためです。

于 2009-07-03T19:32:12.570 に答える
0

Rubyについてもよくわかりません。

しかし、C++ では、次のようにします。

bool IsWholeNumber( float f )
{
    const float delta = 0.0001;
    int i = (int) f;
    return (f - (float)i) < delta;
}

そして、それに基づいて出力精度をフォーマットします。

于 2009-07-03T01:18:47.157 に答える