在Swift中拆分和组合Double

时间:2015-01-31 17:36:05

标签: ios swift math time

我想将时间段存储在Double中,并且需要提取Double(小时和分钟)的高值和低值来访问它们。我还需要能够设置Double两个Intshourminute)。我现在在这里得到了一些东西:

extension Double {
    func hour() -> Int {
        return NSNumber(double: floor(self)).integerValue
    }

    func minute() -> Int {
        return NSNumber(float: Float(Double((self - floor(self)) * 100))).integerValue
    }

    init(hour: Int, minute: Int) {
        self = Double(hour) + ( Double(minute) / 100 )
    }
}

然后我在appDelegate的didFinishLaunchingWithOptions中对此进行了一些测试:

var time: Double = 18.30

NSLog("Time is \"%f\" - so hours is \"%d\" and minutes is \"%d\".", time, time.hour(), time.minute())

time = Double(hour: 10, minute: 1)
NSLog("Time is \"%f\" - so hours is \"%d\" and minutes is \"%d\".", time, time.hour(), time.minute())

time = Double(hour: 15, minute: 45)
NSLog("Time is \"%f\" - so hours is \"%d\" and minutes is \"%d\".", time, time.hour(), time.minute())

现在,此代码有效。有人可能想知道为什么我会在Double函数中将Float转换为minute()。这是因为在将这些Double转换为Float s之前使用Float时未将其转换为Int s时遇到的未知问题。如果分钟未以0结束,则会因为未知原因减去一分钟。
例如, 10:42 返回 10小时和< em> 41分钟。
10:30 10小时 30分钟
10:00 10小时 0分钟

我在这里发布的这个例程似乎有效,但我只是想知道,如果我尽可能高效......这里的转换比需要的更多。
那么,有什么改进吗? / p>

有人知道我提到的减少分钟的未知问题的原因吗?

1 个答案:

答案 0 :(得分:1)

二进制浮点数(例如DoubleFloat)无法准确表示数字10.42,因此 将小数部分乘以100并截断结果可能会得到41。 转换为Float后,您只需要隐藏&#34;问题。

这是舍入而不是截断的版本,总体来说更简单一些。我采用了&#34;分钟&#34;从你的代码, 即使它代表1/100的一小时而不是1/60。

extension Double {

    func hour() -> Int {
        return Int(self)
    }

    func minute() -> Int {
        return Int(round(self * 100.0)) % 100
    }

    init(hour: Int, minute: Int) {
        self = Double(hour) + ( Double(minute) / 100 )
    }
}

解决问题的其他方法:

  • 将持续时间存储为表示总数的整数 分钟数。例如。 &#34; 10:42&#34;将存储为10*60 + 42。 那你根本没有四舍五入的问题。

  • 使用基金会 键入NSDecimalNumber代替Double,代表{{1}} 十进制整数,最多包含38位数字。

相关问题