Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c NSN编号和浮子型铸造异常_Objective C_Casting_Floating Point_Nsnumber - Fatal编程技术网

Objective c NSN编号和浮子型铸造异常

Objective c NSN编号和浮子型铸造异常,objective-c,casting,floating-point,nsnumber,Objective C,Casting,Floating Point,Nsnumber,在我的应用程序中,我使用一个使用json进行通信的外部API。今天我遇到了奇怪的(可能是因为我在iOS方面缺乏经验)浮动和NSNumbers之间的行为。问题是我在API响应中收到了一个浮点值,在这个特殊的例子中是135.99。当本机obj-c json解析器解析响应时,它将使用该值创建NSNumber。它工作得很好。但当我开始使用这个API时,我不知道本机json解析器是如何工作的,所以我一直在做这样的事情: NSNumber * number = [NSNumber numberWithFlo

在我的应用程序中,我使用一个使用json进行通信的外部API。今天我遇到了奇怪的(可能是因为我在iOS方面缺乏经验)浮动和NSNumbers之间的行为。问题是我在API响应中收到了一个浮点值,在这个特殊的例子中是135.99。当本机obj-c json解析器解析响应时,它将使用该值创建NSNumber。它工作得很好。但当我开始使用这个API时,我不知道本机json解析器是如何工作的,所以我一直在做这样的事情:

NSNumber * number = [NSNumber numberWithFloat:[[response objectForKey:@"Number"] floatValue]];
所以,上面所发生的事情实际上是将NSNumber转换为float,并使用该float创建新的NSNumber。这有什么奇怪的?奇怪的是(对我来说)上面这行生成的NSNumber带有值。。。135.99001,而不是正确的135.99


我知道浮点运算真的是一团糟,特别是在像PHP这样的语言中(0.2+0.7不等于0.9),但我没想到在像objective-c这样的语言中,这是c语言的超集,我会发现这样的一团糟。有人对这个问题有很好的解释吗

浮动会发生奇怪的事情。他们的天性之一就是不精确

除此之外,我不完全理解为什么要将漂亮的NSNumber转换为float(而不仅仅是类型转换),只是为了用float创建一个新的NSNumber对象,即使你想不出两个float值应该不同的任何原因,你也不应该期望两个float值相等。 这意味着,当涉及到比较浮动时,您永远不应该比较
float1==float2
。最好比较abs(浮动1-浮动2)<0.001或任何重要意义

关于浮点数的一些一般行为在这个网站上得到了很好的解释:

对于像C这样的语言(我怀疑也是PHP),浮点数(和双精度)算法实际上并不与语言有关,而是与底层硬件有关


对于现代计算机来说,这意味着IEEE浮点运算是由CPU实现的,因此,如果你用C、Pascal、FORTRAN等编写程序,你也会遇到同样的问题。他们都只调用CPU的浮点指令,然后就不使用了。

你犯了一个初学者的错误,那就是假设“float”是浮点数的正确类型。不是。除非你有很好的理由使用float,“double”是你应该使用的类型。JSON解析器将不可避免地使用[NSNumber numberWithDouble:…]来创建它们存储的NSNumber对象(或[NSNumber numberWithLongLong:…]或NSDecimalNumber),但决不会使用[NSNumber numberWithFloat:]


与双精度相比,浮点精度非常有限。可以肯定的是,在大多数情况下,[NSNumber numberWithFloat:…]由于精度有限,将给出不同的结果

所以,上面所发生的事情实际上是将NSNumber转换为float,并使用该float创建新的NSNumber。为什么?如果通过完全避免转换来“修复”代码会发生什么:
NSNumber*number=[response objectForKey:@“number”]
?它工作正常,但我犯了上面提到的错误,我已经解决了。我的问题是为什么会有两个不同的值(135.99和135.99001),而在这两种情况下(135.99)应该有一个相同的值,而不是如何修复它,因为我已经知道了。好吧,如果使用
double
而不是
float
numberWithDouble
doubleValue
)?一般来说,浮点运算并不是真的一团糟。这方面的证据是,许多人对f-p算法的本质、微妙之处和缺陷的理解非常混乱。a我在之前的评论中说这是错误的,因为我不知道json解析器为我创建了NSNumber。我不再那样做了。我只是好奇为什么转换后值会改变。谢谢你的回答,我会查看一下网站。我认为这个网站对这个问题提供了很好的解释,并提供了很好的指南如何处理这个问题。这个问题对于CPU中的数据类型浮点和浮点操作更为普遍。它完全不限于Objective-C或ARM处理器。