Why does Ruby give this large precision decimal result?
I want to convert a subtitle time code:
begin="00:00:07.71" dur="00:00:03.67
to pure seconds:
begin=7.1 end=11.38
I wrote a Ruby code:
def to_sec(value)
a = value.split(':')
a[0].to_i*3600+a[1].to_i*60+a[2].to_f
end
which resulted in 11.379999999999999
.
Can anybody tell me why this happens?
Is there any Time library that can do this开发者_如何学JAVA conversion?
It'll probably be easiest for you to represent your underlying datatype as integer hundredths of a second (centiseconds):
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
You could add some helpers for dealing with the durations and pretty printing them as well:
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
Then your answer is just:
puts SubtitleDuration.new("00:00:07.71", "00:00:03.67").to_s
#=> begin=7.71 end=11.38
This sort of thing can happen in just about any programming language. It's because of how floating point numbers are represented. They're not stored as decimals under the hood, so sometimes you get odd rounding errors like this.
精彩评论