Ruby eval没有圆形

时间:2013-12-22 20:07:19

标签: ruby

我想要使用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')给了我想要的结果,但我不想在字符串中插入任何内容(我准备在必要时将其包装)。

知道如何解决问题?

4 个答案:

答案 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

非常简单,没有额外的库。