iOS - 使用roundf()舍入浮点数不正常 [英] iOS - rounding a float with roundf() is not working properly

查看:124
本文介绍了iOS - 使用roundf()舍入浮点数不正常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了在iPhone应用程序中舍入浮点数的问题。

I am having issue with rounding a float in iPhone application.

float f=4.845;
float s= roundf(f * 100.0)/100;
    NSLog(@"Output-1: %.2f",s);
      s= roundf(484.5)/100;
    NSLog(@"Output-2: %.2f",s);

Output-1: 4.84
Output-2: 4.85

让我知道这个问题以及如何解决这个问题。

Let me know whats problem in this and how to solve this.

推荐答案

问题是你还没有意识到浮点的固有问题:大多数数字不能完全表示(a)

The problem is that you don't yet realise one of the inherent problems with floating point: the fact that most numbers cannot be represented exactly (a).

这意味着 4.845 实际上可能是 4.8449999999999 ,当你绕过它时,它会给你 4.84 而不是你期望的, 4.85

This means that 4.845 is likely to be, in reality, something like 4.8449999999999 which, when you round it, gives you 4.84 rather than what you expect, 4.85.

你最终得到什么价值还取决于你计算它的如何,这就是你得到不同结果的原因。

And what value you end up with also depends on how you calculate it, which is why you're getting a different result.

当然,没有浮点数如果没有权威的什么是每台计算机,那么答案就会完整科学家应该了解F loating-Point Arithmetic

And, of course, no floating point "inaccuracy" answer would be complete on SO without the authoritative What Every Computer Scientist Should Know About Floating-Point Arithmetic.

(a)只有精确权力的总和两个,在某个相似的范围内,可以在IEEE754中精确渲染。因此,例如, 484.5

(a) Only sums of exact powers of two, within a certain similar range, can be exactly rendered in IEEE754. So, for example, 484.5 is

256 + 128 + 64 + 32 + 4 + 0.5 2 8 + 2 7 + 2 6 + 2 5 + 2 2 + 2 -1 )。

256 + 128 + 64 + 32 + 4 + 0.5 (28 + 27 + 26 + 25 + 22 + 2-1).

请参阅此答案更详细地了解IEEE754格式。

See this answer for a more detailed look into the IEEE754 format.

至于解决它,你有几个选择。一种是使用 double 而不是 float 。这样可以提供更高的精度和更大的数字范围,但只能将问题进一步推移而不是真正解决问题。由于 0.1 是IEEE754中的重复分数,因此 no 位数(无穷大)可以完全代表它。

As to solving it, you have a few choices. One is to use double instead of float. That gives you more precision and greater range of numbers but only moves the problem further away rather than really solving it. Since 0.1 is a repeating fraction in IEEE754, no amount of bits (short of infinity) can exactly represent it.

另一个选择是使用像十进制小型的自定义库,它可以表示任意精度的小数(这是无限精度,因为有些人不会建议,因为它受到记忆的限制)。这将减少由二进制/十进制不匹配引起的错误。

Another choice is to use a custom library like a big decimal type, which can represent decimals of arbitrary precision (that's not infinite precision as some people are wont to suggest, since it's limited by memory). This will reduce the errors caused by the binary/decimal mismatch.

您可能还想查看 NSDecimalNumber - 这并没有给你任意精度,但确实给出了一个具有精确十进制表示的大范围。

You may also want to look into NSDecimalNumber - this doesn't give you arbitrary precision but it does give a large range with accurate decimal representation.

仍然有一些你无法代表的数字,比如PI或2的平方根或任何其他无理数,但它应涵盖大多数情况。如果确实需要处理其他值,则需要切换到符号数字表示。

There'll still be numbers you can't represent, like PI or the square root of 2 or any other irrational number, but it should cover most cases. If you really need to handle those other values, you need to switch to symbolic numeric representations.

这篇关于iOS - 使用roundf()舍入浮点数不正常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆