9

R の signif関数に相当するものが Ruby にあるといいですね。

例えば:

>> (11.11).signif(1)
10
>> (22.22).signif(2)
22
>> (3.333).signif(2)
3.3
>> (4.4).signif(3)
4.4 # It's usually 4.40 but that's OK. R does not print the trailing 0's
    # because it returns the float data type. For Ruby we want the same.
>> (5.55).signif(2)
5.6
4

7 に答える 7

14

おそらくもっと良い方法がありますが、これはうまくいくようです:

class Float
  def signif(signs)
    Float("%.#{signs}g" % self)
  end
end

(1.123).signif(2)                    # => 1.1
(11.23).signif(2)                    # => 11.0
(11.23).signif(1)                    # => 10.0
于 2011-12-05T13:57:58.823 に答える
3

以前の回答とコメントのいくつかはこの解決策をほのめかしていましたが、これが私にとってはうまくいきました:

# takes in a float value and returns another float value rounded to 
# given significant figures.    
def round_to_sig_figs(val, sig_figs)
  BigDecimal.new(val, sig_figs).to_f
end
于 2014-11-25T15:05:12.407 に答える
2

Float ではそのようなものは見当たりません。Float は主にネイティブ型のラッパーでありdouble、通常の 2 進数/10 進数の問題を考えると、Float で有効桁数を操作できないことにそれほど驚かない。

ただし、標準ライブラリのBigDecimalは有効数字を認識しますが、繰り返しますが、BigDecimal の有効数字を直接変更できるものはありません。要求することはできますが、変更することはできません。multただし、 oraddメソッドのノーオペレーション バージョンを使用することで、それを回避できます。

require 'bigdecimal'
a = BigDecimal.new('11.2384')
a.mult(1, 2) # the result is 0.11E2   (i.e. 11)
a.add(0, 4)  # the result is 0.1124E2 (i.e. 11.24)

これらのメソッドの 2 番目の引数:

が指定され、結果の有効桁数より少ない場合、結果は に従って、その桁数に丸められBigDecimal.modeます。

BigDecimal を使用すると遅くなりますが、きめの細かい制御が必要な場合や、通常の浮動小数点の問題を回避する必要がある場合は、これが唯一の選択肢になる可能性があります。

于 2011-12-05T09:18:51.873 に答える
2

おそらくRubyのDecimalを探しているでしょう。

次に、次のように記述できます。

require 'decimal/shortcut'
num = 1.23541764
D.context.precision = 2
num_with_2_significant_digits = +D(num.to_s) #  => Decimal('1.2')
num_with_2_significant_digits.to_f #  => 1.2000000000000002

または、同じ構文を使用したい場合は、これを次のようにクラス Float に関数として追加します。

class Float
  def signif num_digits
    require 'decimal/shortcut'
    D.context.precision = num_digits
    (+D(self.to_s)).to_f
  end
end

使用方法は同じです。つまり、

 (1.23333).signif 3
 # => 1.23

使用するには、gem をインストールします。

gem install ruby-decimal
于 2011-12-05T10:25:36.250 に答える