为什么Ruby会给出这个大的精度十进制结果?

时间:2011-06-03 16:23:25

标签: ruby

我想转换字幕时间码:

begin="00:00:07.71" dur="00:00:03.67

到纯秒:

begin=7.1 end=11.38

我写了一个Ruby代码:

def to_sec(value)
        a = value.split(':')
        a[0].to_i*3600+a[1].to_i*60+a[2].to_f
    end

导致11.379999999999999。 谁能告诉我为什么会这样? 有没有可以进行此转换的时间库?

2 个答案:

答案 0 :(得分:0)

这种事情几乎可以在任何编程语言中发生。这是因为浮点数的表示方式。它们并没有存储在引擎盖下,所以有时你会得到奇怪的舍入错误。

答案 1 :(得分:0)

最简单的方法是将基础数据类型表示为整数百分之一秒(厘秒):

     def to_csec(value) #if you had CSec < Integer this would be `def self.[](value)`
        a = value.split(':')
        #tacking on a couple zeros to each
        a[0].to_i*360000+a[1].to_i*6000+(a[2].to_f * 100).to_i
     end

你可以添加一些帮助来处理持续时间并且还可以打印它们:

     def csec_to_s(csec) #if you had CSec < Integer, this would be `def to_sec`
        "%.2f" % (csec.to_f / 100)
     end

    class SubtitleDuration < Range
     def initialize(a,b)
        centi_a = to_csec(a)
        super(centi_a,to_csec(b) + centi_a)
     end
     def to_s
       "begin=#{csec_to_s(self.begin)} end=#{csec_to_s(self.end) }"
     end
    end

然后你的答案就是:

    puts SubtitleDuration.new("00:00:07.71", "00:00:03.67").to_s 
    #=> begin=7.71 end=11.38