Objective c 目标C if语句可能无法正常工作

Objective c 目标C if语句可能无法正常工作,objective-c,Objective C,我很犹豫是否要说出来,因为我知道99.9%的时间用户都应该为错误负责,但我对此感到非常困惑 我在标题中定义了一个名为rotation的浮点: @property(nonatomic)float rotation; 在给旋转一个值之后,我使用这个if语句检查它 if (fabsf(rotation) == M_PI_2) { NSLog(@"Execute more code now"); } 现在我检查了M_PI_2的定义,得出了1.5707966326794896619231321

我很犹豫是否要说出来,因为我知道99.9%的时间用户都应该为错误负责,但我对此感到非常困惑

我在标题中定义了一个名为rotation的浮点:

@property(nonatomic)float rotation;
在给旋转一个值之后,我使用这个if语句检查它

if (fabsf(rotation) == M_PI_2)
{
    NSLog(@"Execute more code now");
}
现在我检查了M_PI_2的定义,得出了
1.570796632679489661923132169163975144

我注意到它不起作用,所以我在if语句之前放了另一个NSLog:

    NSLog(@"%f == %f", fabs(rotation), M_PI_2);
以下是我得到的结果:

2014-06-26 16:29:40.831 76J284E[82085:60b] 0.000000 == 1.570796
2014-06-26 16:29:40.834 76J284E[82085:60b] 3.141593 == 1.570796
2014-06-26 16:29:44.653 76J284E[82085:60b] 0.000000 == 1.570796
2014-06-26 16:29:44.658 76J284E[82085:60b] 3.141593 == 1.570796
2014-06-26 16:29:47.951 76J284E[82085:60b] 0.000000 == 1.570796
2014-06-26 16:29:47.953 76J284E[82085:60b] 3.141593 == 1.570796
2014-06-26 16:29:54.305 76J284E[82085:60b] 0.000000 == 1.570796
2014-06-26 16:29:54.310 76J284E[82085:60b] 1.570796 == 1.570796
2014-06-26 16:29:54.313 76J284E[82085:60b] 4.712389 == 1.570796
2014-06-26 16:29:54.318 76J284E[82085:60b] 3.141593 == 1.570796
这些不应该触发if语句吗?我做错了什么,谢谢

编辑


我应该补充一点,我用M_PI_2定义旋转(在某些时候)

数字不相等,只是没有打印浮点数字的完整值。这是关于C++的,但是同样的原理也适用。

数字不相等,只是打印不出浮点数的全部值。这是关于C++的,但原理相同。

< P>有两个问题。您将M_PI_2定义为1.570796362679489661923132169163975144,并尝试查看它是否等于1.570796。几乎相等,但不完全相等。如果这些数字是我账户中有多少万亿美元,我宁愿它们不相等,而采用M_PI_2


其次,由于浮点计算错误,无法直接比较浮点数字。关于这个问题有一个很好的讨论有两个问题。您将M_PI_2定义为1.570796362679489661923132169163975144,并尝试查看它是否等于1.570796。几乎相等,但不完全相等。如果这些数字是我账户中有多少万亿美元,我宁愿它们不相等,而采用M_PI_2


其次,由于浮点计算错误,无法直接比较浮点数字。这里有一个关于这个问题的很好的讨论

你的问题是M_PI_2是一个双精度函数,旋转是一个浮点数。本声明:

浮动旋转=M_PI_2

取双精度常数M_PI_2,将其四舍五入为浮点精度(丢弃29位尾数),然后将其指定为旋转

稍后检查舍入值是否与未舍入值匹配。没有因为它被四舍五入了

尝试定义M_PI_2 1.570796

没有。1.570796仍然是双精度的,不能用浮点数或双精度表示,因此仍然存在舍入问题。试试这个:

常量浮点M_PI_2=1.570796632679489661923132169163975144F

浮动旋转=M_PI_2

如果(旋转==M_PI_2)

将常数赋给浮点和/或在常数后面加上“f”就可以了

有关详细信息:

另外,当打印浮动时,您需要打印尾数的九位数,否则您不知道您有什么浮动。双打需要17位尾数。有关更多信息:


您的问题是M_PI_2是双精度的,旋转是浮动的。本声明:

浮动旋转=M_PI_2

取双精度常数M_PI_2,将其四舍五入为浮点精度(丢弃29位尾数),然后将其指定为旋转

稍后检查舍入值是否与未舍入值匹配。没有因为它被四舍五入了

尝试定义M_PI_2 1.570796

没有。1.570796仍然是双精度的,不能用浮点数或双精度表示,因此仍然存在舍入问题。试试这个:

常量浮点M_PI_2=1.570796632679489661923132169163975144F

浮动旋转=M_PI_2

如果(旋转==M_PI_2)

将常数赋给浮点和/或在常数后面加上“f”就可以了

有关详细信息:

另外,当打印浮动时,您需要打印尾数的九位数,否则您不知道您有什么浮动。双打需要17位尾数。有关更多信息:


尝试定义M_PI_2
1.570796
not
1.570796632679489661923132169163975144
您希望匹配的精确程度如何?您的nslog仅显示6位小数精度。您必须进行一些舍入或实现子字符串,以允许不太精确的匹配。@jackjop我曾想过这一点,但刚刚测试过,没有运气。是不是我只需要找到正确数量的地方?我以前用int做过这个。@jackjop没有帮助,因为fabsf只是abs的一个不同版本,但用于float,所以它肯定会返回一个float(但我仍然尝试了,但它不起作用)。没有这个
if(fabsf(rotation)==M_PI_2.f)
——我糟糕的悲伤定义了M_PI_2
1.570796
not
1.57079636267948966192313216916397575144
你认为匹配的精确程度如何?您的nslog仅显示6位小数精度。您必须进行一些舍入或实现子字符串,以允许不太精确的匹配。@jackjop我曾想过这一点,但刚刚测试过,没有运气。是不是我只需要找到正确数量的地方?我以前用int做过这个。@jackjop没有帮助,因为fabsf只是abs的一个不同版本,但用于float,所以它肯定会返回一个float(但我仍然尝试了,但它不起作用)。没有这个
if(fabsf(rotation)==M_PI_2.f)
——我的坏毛病我之所以难以相信这一点,唯一的问题是因为我用M_PI_2定义了旋转。浮点不能保证是关联的或分配的。如果
旋转
是一个
浮点
,但是
M_PI_2
是一个
双精度
,然后
rotation=M_PI_2
double
转换为
float
,失去精度。然后比较
rotation==M_PI_2
时,浮点值被提升为double,但它不会返回丢失的信息