Ios Swift中Double的拆分与合并
我想将持续时间存储在Ios Swift中Double的拆分与合并,ios,swift,math,time,Ios,Swift,Math,Time,我想将持续时间存储在Double中,并需要提取Double的高值和低值(小时和分钟)以访问它们。我还需要能够设置两个整数(小时和分钟)的双精度。我现在得到了一些东西: extension Double { func hour() -> Int { return NSNumber(double: floor(self)).integerValue } func minute() -> Int { return NSNumber(
Double
中,并需要提取Double
的高值和低值(小时和分钟)以访问它们。我还需要能够设置两个整数(小时和分钟)的双精度。
我现在得到了一些东西:
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())
现在,这段代码起作用了。有人可能想知道为什么我在minute()
函数中将Double
转换为Float
。这是因为在将这些Float
s转换为Int
s之前,我在使用Double
s而不将它们转换为Float
s时遇到了一个未知问题。如果分钟没有以0
结束,则会因未知原因减去一分钟。
例如,10:42返回10小时41分钟。
但10:30仍然是10小时30分钟。
同样,10:00是10小时0分钟
我在这里发布的这个程序似乎很有效,但我只是想知道,我是否尽可能的高效。。。这里的转换比需要的要多。
那么,有什么改进吗
有人知道我提到的递减分钟未知问题的原因吗?二进制浮点数,如Double
或Float
不能准确地表示数字10.42
将分数部分乘以100并截断结果可能得到41
。
转换为Float
时,您只是在“隐藏”问题
这是一个舍入而不是截断的版本,总体来说比较简单。我采用了你代码中的“分钟”符号,
即使它代表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 )
}
}
解决问题的其他可能方法:
- 将持续时间存储为表示总持续时间的整数
分钟数。例如,“10:42”将存储为
10*60+42
。
那么你就没有任何舍入问题了
运用基础
键入
NSDecimalNumber
,而不是可以表示
精确到38位的十进制整数
那么您的小时有100分钟?通常我们将持续时间存储为秒数(即小时*60*60+分钟*60
)。标准库支持这一点,如果以这种方式存储,则可以对持续时间进行算术运算。为什么要将持续时间存储为hour+minute/100
?我想使用一个带有两个组件的选择器,用于输入持续时间-这就是Double的扩展可以使事情变得非常简单的地方。。我也可以使用我自己的一种方法,或nsdate或许多其他方法,但在我看来这是一个最简单的解决方案。。杰克:好吧,这取决于你。我试图解释舍入问题,提出了一些解决方法和替代方案。如果您需要更多信息,请告诉我。是的-嗯,它只是一个容器,应该尽可能具有通用性-我想我可能能够在其他项目上重复使用我的代码,所以这就是我选择这种方式存储数据的原因-我的小时有100分钟根本不是问题,因为这里不应该进行计算,我只是想让我的picker视图返回一些值——我可以创建自己的类型、使用数组、字典等等。。但这似乎是一个最好的方法——实际上可能不是最好的方法,但我将采用这种方法,以及您的替代方案。。效果非常好。非常感谢。