ios - 与 NSNumber 的值不一致的双倍乘法

标签 ios objective-c nsnumber nsnumberformatter

我目前正在将 NSString 值解析为 NSNumbers,然后将它们添加到名为“data”的对象中的名为操作数的 NSMutableArray 中,例如所以:

NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:*operandString];
[data.operands addObject:myNumber];

然后我检索这些数字,对它们执行一些数学运算,然后更新数组:

double x = [[data.operands objectAtIndex: i]doubleValue];
double y = [[data.operands objectAtIndex: i + 1]doubleValue];
double answer = x * y;
[data.operands replaceObjectAtIndex:(i) withObject:[NSNumber numberWithDouble:answer]];

当我得到答案时,一切看起来都很好,例如:( 3.33 * 5 = 16.65)

但是,当我查看调试器时,我看到 x 和答案有一些疯狂的值,例如:

x = 3.3300000000000001
答案=16.649999999999999

为什么会发生这种情况?我在解析这些后面和第四个内容时是否会失去一些精度?这是我使用 NSNumberFormatter 解析字符串的方式吗?

我遇到这个问题的原因是因为我试图确保不存在双重溢出错误,因此我使用这个简单的测试来检查完整性:

    if (answer / y != x){
        //THROW OVERFLOW ERROR
    }

对于上述疯狂的数字,这总是不一致的。当我 NSLog 时,答案很好:

NSLog (@"%g", [[data.operands objectAtIndex:i]doubleValue]]);

同样

NSLog (@"%f", [[data.operands objectAtIndex:i]doubleValue]]);

最佳答案

您不会失去任何需要担心的精度。这些是正确的值(value)观。只有大约 2^60 个不同的 double ,该有限集必须尝试大约覆盖 double 覆盖范围内的无限“数字数量”。

换句话说,在计算机领域和你的领域中没有确切的答案

   if (answer / y != x){
       //THROW OVERFLOW ERROR
   }

不会工作。或者它可能在大部分时间都有效,但如果你插入它就会失败。相反,您需要承认 double 的有限精度(这是相当高的精度):

  //Don't waste time worrying like this...
  if (fabs(answer / y - x) > 1e-12*fabs(answer)){
       //Not correct or useful thing to check don't use this - i did not check 
   }


   // let the math package handle it:
   if (isnan(answer)){
     // we gots problems
   }

   if (!isnormal(answer)){
     // we gots some other problems
   }

另外不要忘记 10^300 是一个非常大的数字, double 效果很好。要使用 32 位 float ,您需要更加注意执行顺序等。

NSLog 可能会以更少的小数位数输出,并四舍五入到最接近的值,因此答案看起来更好。

关于ios - 与 NSNumber 的值不一致的双倍乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23854885/

相关文章:

iphone - 如何取消 NSOperationQueue

ios - 如何避免对加密 key 进行硬编码( Objective-C )?

ios - 如何定位 SCNCamera 以便在 View 中看到对象 "just fits"?

ios - 将日期和时间转换为时间戳

ios - 我应该在 iPhone/iPad 类中使用 NSNumber 还是 int?

iphone - 如何在iphone、xcode中播放视频

objective-c - ASIHTTPRequest 在请求 :willRedirectToUrl: is implemented 时停止下载

android - iOS控件像android一样隐藏和消失

image - 本地镜像作为整数返回 - React Native

ios - 核心数据、NSNumber、整数 32 和整数 64