【问题标题】:SBJSON Float in NSDictionary written to NSString incorrectNSDictionary 中的 SBJSON Float 写入 NSString 不正确
【发布时间】:2013-01-23 16:11:15
【问题描述】:

我在一个项目中使用 SBJSON,我正在尝试从字典中构建一个 json 字符串。

这是怎么回事,我将浮点数作为 NSNumbers 放入字典中:

NSDictionary* tempdic = [[NSDictionary alloc] init];
tempdic = [NSDictionary dictionaryWithObjectsAndKeys:productId, @"productId", [NSNumber numberWithFloat:quantity], @"aantal", price, @"price" , nil];
        [orders addObject:tempdic];
NSDictionary* json = [NSDictionary dictionaryWithObjectsAndKeys: orders, @"order", message, @"message", [NSNumber numberWithFloat:orderprice], @"totalPrice",dueDate,@"dueDate", nil];

然后最后把它写成一个json字符串,我尝试了这三个。

1)

NSData* jsonData = [writer dataWithObject:json];
NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

2)

NSString* jsonString = [json JSONRepresentation];

3)

NSString* jsonString = [writer stringWithObject:json];

这些变化中的每一个都从 0.95 变为 0.95000000000000034355 或更糟的是 0.9499999999999999992344 或类似的东西。

为什么会这样?我怎样才能防止这种情况? 谢谢

【问题讨论】:

    标签: ios nsstring nsdictionary sbjson


    【解决方案1】:

    这是浮点值的基本问题。您不能存储不能用2 的幂之和表示的值。从而得到浮点的近似值。

    例如1.25 可以很容易地表示为 2 的幂的总和
    1*2^0 +1*2^-2,但如果您要将1.33 表示为2 的幂的总和,那么结果将是1*2^0 + 1*2^-2 + 1*2^-4 + 1*2^-8 + 1*2^-9 ....

    只需阅读 wiki 上的 Representable numbers, conversion and rounding
    你可以检查你的浮点表示using online tool

    【讨论】:

    • 当您再次将其转换回浮点数时,它会显示 .95 或者当您将其转换为字符串时使用 %.2f 以便它会为您提供小数点后的 2 位数字
    • json 文件被发送到服务器再次解析。所以服务器必须正确地舍入它?我只是想知道是否有办法在应用程序中做到这一点。
    • 这些东西会一直存在,所以不需要做任何事情。只需按原样传递这些值。假设您的服务器/应用程序将您的字符串 0.949999999999999992344 转换为 0.95,因为这是一个浮点值,因此您的服务器/应用程序将再次将这些值存储到浮点变量,从而产生相同的值 0.949999999999999992344
    • 此外,这些进动损失很小,不会影响您的数据。除非你继续乘以导致你的精度损失越来越多。
    【解决方案2】:

    这是浮点数的经典问题。但是,您可以使用NSDecimalNumber 而不是NSNumber 来获得更高的精度(以降低范围的数字为代价)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 2014-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多