我想要使用ruby eval评估一个已清理的字符串。该字符串可以包含任何简单的算术公式,如'44 / 5'。
问题是eval('44/5')
的结果是8(而不是8.8)。
它作为评估的一部分发生(因为1.0*eval('44/5')
给出了8.0)。
我没有为eval找到任何额外的参数来管理它。
我甚至试图将字符串前置或包装以将其转换为:
'0.0+44/5'
或
'1.0*(44/5)'
但它仍然没有给我8.8。
eval('44.0/5')
给了我想要的结果,但我不想在字符串中插入任何内容(我准备在必要时将其包装)。
知道如何解决问题?
答案 0 :(得分:8)
这是使用Rational#to_f
:
Rational('44/5').to_f # => 8.8
'44/5'.to_r.to_f # => 8.8
答案 1 :(得分:4)
您也可以使用mathn
from Ruby's core library:
require 'mathn'
res = eval('44/5') #=> (44/5)
res.to_f #=> 8.8
此库将在适当时自动转换为有理数。
答案 2 :(得分:0)
我没有为eval找到任何额外的参数来管理它。
因为eval
适用于所有事物,不仅仅是数学方程式。
Arup的solution看起来更好,但这是我的:
str = '4/5'
eval('1.0*'+ str) #0.8
PS。第二个字符串(1.0*(44/5)
)将无效,因为首先评估(44/5)
(8 =整数),然后乘以1.0
(= 8.0)。
答案 3 :(得分:0)
不确定为什么没有人提到强迫浮子将浮子放在除数中。即
eval('44/5')
#=> 8
eval('44/5.0')
#=> 8.8
虽然如果你对字符串缺乏控制,可能会更困难,但这可行
eval('44/5'.split("/").map(&:to_f).join("/"))
#=> 8.8
使用eval处理多个关节符号
pattern = /([0-9]\.?[0-9]+|[0-9]+|[+-\/*\(\)])/
str = "2+3/4"
str.scan(pattern).flatten.map{|e| e =~(/[0-9]/) ? e.to_f : e}
#=> [2.0,"+",3.0,"/",4.0]
str.scan(pattern).flatten.map{|e| e =~(/[0-9]/) ? e.to_f : e}.join
#=> "2.0+3.0/4.0"
eval(str.scan(pattern).flatten.map{|e| e =~(/[0-9]/) ? e.to_f : e}.join)
#=> 2.75
也适用于括号和现有花车
str = "(2+3)/4"
eval(str.scan(pattern).flatten.map{|e| e =~(/[0-9]/) ? e.to_f : e}.join)
#=> 1.25
str = "(2.3+1)/4"
eval(str.scan(pattern).flatten.map{|e| e =~(/[0-9]/) ? e.to_f : e}.join)
#=> 0.825
Rational方法问题
str = "(2.3+3)/4*2"
str.to_r.to_f
#=>0.0
eval(str.scan(pattern).flatten.map{|e| e =~(/[0-9]/) ? e.to_f : e}.join)
#=> 2.65
非常简单,没有额外的库。