Objective C与Swift数学运算

时间:2018-08-28 01:19:31

标签: objective-c swift

在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

有人知道为什么会有区别吗?

3 个答案:

答案 0 :(得分:3)

差异是整数与浮点除法。在整数除法中,小数部分将被忽略。一些简单的示例是1 / 2 = 02 / 3 = 0,但1.0 / 2.0 = 0.52.0 / 3.0 = 0.67

让我们细分一下两种语言的代码工作方式:

Objective-C

假设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的字面常量时都有一些余地:可以看到intdouble

  • 我不知道ObjC编译器的确切内部工作原理。您只需在C中混合数字类型时要小心。
  • Swift试图通过强制所有操作数具有相同的数据类型来避免这种混淆。由于aDouble,所以解释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时精度下降。