在Objective-C和Swift中执行以下操作将返回不同的结果:
输入23492.4852,
Objective-C功能:
+ (double)funTest:(double)a {
return a - (int) a / 360 * 360;
}
返回92.48521
快捷功能:
class func funTest(a: Double) -> Double {
return a - Double(Int(a)) / 360 * 360
}
返回0.48521
有人知道为什么会有区别吗?
答案 0 :(得分:3)
差异是整数与浮点除法。在整数除法中,小数部分将被忽略。一些简单的示例是1 / 2 = 0
或2 / 3 = 0
,但1.0 / 2.0 = 0.5
和2.0 / 3.0 = 0.67
。
让我们细分一下两种语言的代码工作方式:
假设a = 23492.4852
:
a - (int) a / 360 * 360 = a - ((int) a) / 360 * 360
= a - 23492 / 360 * 360 // integer division
= a - 65 * 360
= 23492.4852 - 23400
= 92.4852
Objective-C从C继承了type promotion rules,这很容易记住。
假设a = 23492.4852
:
a - Double(Int(a)) / 360 * 360 = a - Double(23492) / 360 * 360 // floating point division
= a - 65.2556 * 360
= a - 23492
= 23492.4852 - 23492
= 0.4852
在两种情况下,编译器在解释360
的字面常量时都有一些余地:可以看到int
或double
。
a
是Double
,所以解释360
的唯一方法是它也必须是Double
。答案 1 :(得分:1)
有人知道为什么会有区别吗?
您刚刚犯了一个简单的分组错误。
如您所见,从浮点值转换为整数时,Objective-C和Swift都需要强制转换,因此您为前者写了(int)a
,为后者写了Int(a)
您还了解到,从整数到浮点值的转换在两种语言中是不同的,在Objective-C(以及C和许多其他语言)中,转换是隐式,而在迅速,这是明确的。
您犯的唯一错误是在解析Objective-C并因此产生了错误的Swift 或,而您只是错误地键入了Swift。
在算术表达式中,运算符是根据优先级求值的,与您的问题类型相关的转换将紧紧地绑定到以下表达式,然后进行乘法和除法,然后进行加减运算。这意味着您的Objective-C:
a - (int) a / 360 * 360
解析为:
a - (double) ( (int) a / 360 * 360 )
请注意,(double)
强制转换适用于表达式(int) a / 360 * 360
的结果。您在Swift中编写的内容是:
a - Double(Int(a)) / 360 * 360
这是不相同的,此处的转换仅适用于Int(a)
。您应该写的是:
a - Double(Int(a) / 360 * 360)
像Objective-C一样将强制类型转换应用于Int(a) / 360 * 360
。
通过两种语言的校正,乘法和除法都对整数进行运算,整数除法被截断(例如9/4为2而不是2.25)。由于Swift中括号的位置不正确,所以乘法和除法都对浮点值进行运算。
TL; DR:您只是放错了括号。
HTH
答案 2 :(得分:0)
这是由于编译器如何看到数字。请注意,在将a
强制转换为Int
之后,您必须迅速将其强制转换为double吗?迅捷的编译器将整个表达式视为Double
,因此,当您执行Double(Int(a)) / 360 * 360
时,您会得到23492 / 360 * 360 = 65.25555... * 360 = 23492.4852
。但是,在C / C ++ / Obj-C等中,它将23492 / 360
看作是给定23492 / 360 * 360 = 65 * 360 = 23400
的整数除法。这就是90的来源(是因为在C中除以2 int
s时精度下降。