【问题标题】:Objective-c NSNumber floatValue returns wrong value [duplicate]Objective-c NSNumber floatValue返回错误值[重复]
【发布时间】:2022-01-16 00:06:39
【问题描述】:

我在 macOS 上,objective-c。不是 swift,不是 iOS。

为了传递一个浮点数,我暂时需要在某个点使其成为一个对象:

NSNumber* floatNumber = @.5;
// Other stuff ...
float myFloat = [floatNumber floatValue]; // --> (float) 0.5

但是,与上面的操作相同

NSNumber* floatNumber = @.4;
// Other stuff ...
float myFloat = [floatNumber floatValue]; // --> (float) 0.400000006

这会破坏其余部分,因为我需要相同的浮点值 0.4

我已经尝试过四舍五入

floorf([floatNumber floatValue] *100)/100;  // --> (float) 0.400000006

谁能解释一下这种行为并告诉我如何解决它

【问题讨论】:

    标签: objective-c numbers precision


    【解决方案1】:

    此行为与浮点错误有关。

    根据定义,浮点错误无法消除,并且,在 最好,只能管理。

    https://en.wikipedia.org/wiki/Floating-point_error_mitigation

    您看到的错误与浮点只能存储有限的精度有关,因此经过一定数量的位置后,它会开始看起来像噪音。几乎可以肯定,在您使用 0.5 的第一个示例中存在一些错误,但它足够小,以至于在打印时没有显示出来。

    改善这种情况的一种方法是使用 double 而不是 float 。在 64 位架构(即任何现代架构)上,NSNumber 在内部将浮点值存储为双精度值。因此,如果您使用doubleValue 而不是floatValue,您将获得更高精度的版本。

    请注意,仍然会有 错误。这只是浮点的方式。您可以将 0.4 存储在浮点数或双精度数中,但实际上这意味着“接近 0.4”。使用整数和定点类型,没有错误。

    【讨论】:

      猜你喜欢
      • 2011-02-18
      • 2011-12-28
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多