我认为标题说明了一切,但让我再谈谈它了。
当用户使用我的应用时,我每隔5分钟在数据库中存储十进制小时数。我在显示5分钟块的正确时间时遇到了一些麻烦,因为它显示4分60秒。每隔3分钟5分钟显示一次。
这样的事情
4:60
10:00
15:00
19:60
有些甚至有n:59而不是n:00
部分代码是:
let hours = Int(floor(decimalHour))
let mins = Int(floor(decimalHour * 60) % 60)
let secs = Int(floor(decimalHour * 3600) % 60)
有什么建议我可能做错了吗?
答案 0 :(得分:3)
二进制浮点数不能代表所有数字 确切地说,因此您的代码容易出现舍入错误。 示例(Swift 2):
let decimalHour = 1.0 + 5.0/60.0
print(decimalHour.debugDescription) // 1.0833333333333333
print(floor(decimalHour * 3600)) // 3899.0
let hours = Int(floor(decimalHour))
let mins = Int(floor(decimalHour * 60) % 60)
let secs = Int(floor(decimalHour * 3600) % 60)
print(hours, mins, secs) // 1 5 59
decimalHour
中存储的实际数字略小于1 + 5/60
,因此错误地计算了秒数。
(另请注意,您不能将%
与浮点数一起使用
在Swift 3中,比较What does "% is unavailable: Use truncatingRemainder instead" mean?。)
正如评论中所说,更好的方法是 将持续时间存储为整数(秒数)。
如果无法做到,将浮点数编号为 a秒数然后继续使用纯整数 算术。示例(适用于Swift 2 + 3):
let decimalHour = 1.0 + 5.0/60.0
let totalSeconds = lrint(decimalHour * 3600) // round to seconds
let hours = totalSeconds / 3600
let mins = (totalSeconds % 3600) / 60
let secs = totalSeconds % 60
print(hours, mins, secs) // 1 5 0