【问题标题】:Decimal hour shows 4 min 60 seconds not 5 minutes十进制小时显示 4 分 60 秒而不是 5 分钟
【发布时间】:2017-05-03 14:07:30
【问题描述】:

我认为标题说明了一切,但让我再深入一点。

当用户使用我的应用程序时,我每 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)

有什么建议我可能做错了吗?

【问题讨论】:

  • floor(x) % 60 永远不会给你 60(或者它可能会为浮点数提供?在执行% 之前尝试转换为int)请显示更多代码。还包括decimalHour 对这些测试用例的值。
  • 如果可能,最好将持续时间存储为秒(整数)而不是小数小时(浮点)。
  • 使用let mins = Int(floor(decimalHour * 60)) % 60

标签: swift


【解决方案1】:

二进制浮点数不能代表所有数字 确切地说,因此您的代码容易出现舍入错误。 示例(斯威夫特 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?。)

正如 cmets 中已经说过的,更好的方法是 将持续时间存储为整数(秒数)。

如果不可能,四舍五入浮点数 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

【讨论】:

    猜你喜欢
    • 2022-01-16
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    相关资源
    最近更新 更多