在Ruby中拥有等效的R's signif函数会很好。
例如:
>> (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
答案 0 :(得分:13)
可能有更好的方法,但这似乎工作正常:
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
答案 1 :(得分: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
答案 2 :(得分:2)
在Float中我没有看到类似的东西。 Float主要是原生double
类型的包装器,并且给出了通常的二进制/小数问题,我并不感到惊讶Float不允许你操纵有效数字。
但是,标准库中的BigDecimal确实理解有效数字,但是我再也没有看到任何允许您直接更改BigDecimal中有效数字的内容:您可以要求它但是您不能更改。但是,您可以使用mult
或add
方法的无操作版本来解决这个问题:
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)
这些方法的第二个参数:
如果指定且小于结果的有效位数,则根据
BigDecimal.mode
将结果四舍五入到该位数。
使用BigDecimal会比较慢,但如果您需要精细控制或者需要避免通常的浮点问题,它可能是您唯一的选择。
答案 3 :(得分: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
答案 4 :(得分:2)
这是一个不使用字符串或其他库的实现。
class Float
def signif(digits)
return 0 if self.zero?
self.round(-(Math.log10(self).ceil - digits))
end
end
答案 5 :(得分:0)
@ Blou91的答案几乎就在那里,但它返回一个字符串,而不是一个浮点数。以下内容对我有用:
(sprintf "%.2f", 1.23456).to_f
所以作为一个功能,
def round(val, sig_figs)
(sprintf "%.#{sig_figs}f", val).to_f
end
答案 6 :(得分:-2)
如果要打印尾随零,请使用sprintf
2.0.0-p353 :001 > sprintf "%.3f", 500
=> "500.000"
2.0.0-p353 :002 > sprintf "%.4f", 500
=> "500.0000"
2.0.0-p353 :003 >