浮点舍入错误 [英] Floating point rounding error

查看:67
本文介绍了浮点舍入错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么浮点有舍入误差?如何解决这个问题?


例如,以下内容:


flaot f = 1234.12345678F;


printf("%2f \ n",f)//打印1234.123413




printf(" %8.9f \ n",f)//打印1234.123413086

Why does floating point have a rounding error? How to work around it?

For example, the following:

flaot f = 1234.12345678F;

printf("%2f\n", f) //prints 1234.123413

and

printf("%8.9f\n", f) //prints 1234.123413086

推荐答案

Mu *************** @ yahoo.com 说:

为什么浮点有舍入误差?
Why does floating point have a rounding error?



考虑1234.12345678


处理1234很容易。以下是位:10011010010

所以让我们尝试使用二进制表示法处理0.12345678。


所以0.1(二进制)是0.5(十进制),0.01(二进制) )是0.25(十进制),并且

等等。

0.1 = 1/2 = 0.5 - 太大

0.01 = 1/4 = 0.25 - 太大了

0.001 = 1/8 = 0.125 - 太大了

0.0001 = 1/16 = 0.0625 - 太小了

0.00011 = 3/32 = 0.09375 - 太小了

0.000111 = 7/64 = 0.109375 - 太小了

0.0001111 = 15/128 = 0.1171875 - 太小了

0.00011111 = 31/256 = 0.12109375 - 太小

0.000111111 = 63/512 = 0.123046875 - 太小

0.0001111111 = 127/1024 = 0.1240234375 - 太大

0.00011111101 = 253/2048 = 0.12353515625 - 太大了

0.000111111001 = 505/4096 = 0.123291015625 - 太小了

0.0001111110011 = 1011/8192 = 0.1234130859375 - 太小了

0.00011111100111 = 2023/16384 = 0.12347412109375 - 太大了

0.000111111001101 = 4045/32768 = 0.123443603515625 - 太小了

0.0001111110011011 = 8091/65536 = 0.1234588623046875 - 太大


到目前为止,我们已经使用了16位。继续计算'',然后找出

如果要获得* b $ b 0.12345678的*精确*表示,你需要多少位数。您可能会对结果感到惊讶。

Consider 1234.12345678

It''s easy enough to deal with 1234. Here are the bits: 10011010010

So let''s try to deal with 0.12345678, using binary notation.

So 0.1 (binary) is 0.5 (decimal), 0.01 (binary) is 0.25 (decimal), and
so on.
0.1 = 1/2 = 0.5 - too large
0.01 = 1/4 = 0.25 - too large
0.001 = 1/8 = 0.125 - too large
0.0001 = 1/16 = 0.0625 - too small
0.00011 = 3/32 = 0.09375 - too small
0.000111 = 7/64 = 0.109375 - too small
0.0001111 = 15/128 = 0.1171875 - too small
0.00011111 = 31/256 = 0.12109375 - too small
0.000111111 = 63/512 = 0.123046875 - too small
0.0001111111 = 127/1024 = 0.1240234375 - too large
0.00011111101 = 253/2048 = 0.12353515625 - too large
0.000111111001 = 505/4096 = 0.123291015625 - too small
0.0001111110011 = 1011/8192 = 0.1234130859375 - too small
0.00011111100111 = 2023/16384 = 0.12347412109375 - too large
0.000111111001101 = 4045/32768 = 0.123443603515625 - too small
0.0001111110011011 = 8091/65536 = 0.1234588623046875 - too large

So far, we''ve used 16 bits on this. Keep on calculatin'', and find out
how many bits you need if you''re to get an *exact* representation of
0.12345678. You might well be surprised by the result.


如何解决这个问题?
How to work around it?



这取决于你想要达到的目标。


-

Richard Heathfield

Usenet是一个奇怪的地方 - dmr 29/7/1999
http://www.cpax.org.uk

电子邮件:rjh在上述域名, - www。

That depends on what you want to achieve.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.


6月16日下午4:32,Richard Heathfield< ; r ... @ see.sig.invalidwrote:
On Jun 16, 4:32 pm, Richard Heathfield <r...@see.sig.invalidwrote:

Mukesh_Singh_N ... @ yahoo.com说:
Mukesh_Singh_N...@yahoo.com said:

为什么浮点有舍入误差?
Why does floating point have a rounding error?



考虑1234.12345678


处理1234很容易。以下是位:10011010010

所以让我们尝试使用二进制表示法处理0.12345678。


所以0.1(二进制)是0.5(十进制),0.01(二进制) )是0.25(十进制),并且

等等。

0.1 = 1/2 = 0.5 - 太大

0.01 = 1/4 = 0.25 - 太大了

0.001 = 1/8 = 0.125 - 太大了

0.0001 = 1/16 = 0.0625 - 太小了

0.00011 = 3/32 = 0.09375 - 太小了

0.000111 = 7/64 = 0.109375 - 太小了

0.0001111 = 15/128 = 0.1171875 - 太小了

0.00011111 = 31/256 = 0.12109375 - 太小

0.000111111 = 63/512 = 0.123046875 - 太小

0.0001111111 = 127/1024 = 0.1240234375 - 太大

0.00011111101 = 253/2048 = 0.12353515625 - 太大

0.000111111001 = 505/4096 = 0.123291015625 - 太小

0.0001111110011 = 1011/8192 = 0.1234130859375 - 太小了

0.00011111100111 = 2023/16384 = 0.12347412109375 - 太大了

0.000111111001101 = 4045/32768 = 0.123443603515625 - 太小了

0.0001111110011011 = 8091/65536 = 0.1234588623046875 - 太大


到目前为止,我们已经使用了16位。继续计算'',然后找出

如果要获得* b $ b 0.12345678的*精确*表示,你需要多少位数。您可能会对结果感到惊讶。


Consider 1234.12345678

It''s easy enough to deal with 1234. Here are the bits: 10011010010

So let''s try to deal with 0.12345678, using binary notation.

So 0.1 (binary) is 0.5 (decimal), 0.01 (binary) is 0.25 (decimal), and
so on.
0.1 = 1/2 = 0.5 - too large
0.01 = 1/4 = 0.25 - too large
0.001 = 1/8 = 0.125 - too large
0.0001 = 1/16 = 0.0625 - too small
0.00011 = 3/32 = 0.09375 - too small
0.000111 = 7/64 = 0.109375 - too small
0.0001111 = 15/128 = 0.1171875 - too small
0.00011111 = 31/256 = 0.12109375 - too small
0.000111111 = 63/512 = 0.123046875 - too small
0.0001111111 = 127/1024 = 0.1240234375 - too large
0.00011111101 = 253/2048 = 0.12353515625 - too large
0.000111111001 = 505/4096 = 0.123291015625 - too small
0.0001111110011 = 1011/8192 = 0.1234130859375 - too small
0.00011111100111 = 2023/16384 = 0.12347412109375 - too large
0.000111111001101 = 4045/32768 = 0.123443603515625 - too small
0.0001111110011011 = 8091/65536 = 0.1234588623046875 - too large

So far, we''ve used 16 bits on this. Keep on calculatin'', and find out
how many bits you need if you''re to get an *exact* representation of
0.12345678. You might well be surprised by the result.


如何解决这个问题?
How to work around it?



这取决于你想要达到的目标。


-

Richard Heathfield

Usenet是一个奇怪的地方 - dmr 29/7 / 1999http://www.cpax.org.uk

电子邮件:rjh在上述域名, - www。


That depends on what you want to achieve.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.



感谢您回复一个非常精细的例子,理查德。如果我告诉你,我会对你的二进制形式的非整数十进制数字的表示感兴趣,我会对你感到失望。


我知道带积分的二进制算术。我有时想知道并且

从不打扰我自己如何将小数表示为二进制文件。

我想了解你的例子。


我可以在表示中看到一个模式。


0.1是一半。

0.01是右移,你进一步减半。

0.001两个右移进一步将它减半等等。


你以0.011失去了我。我可以请你解释。


Thank you for replying with a very elaborate example, Richard. I would
disappoint you if I told you I am intrigued by the representation of
non-integral decimal numbers in their binary form.

I know binary arithmetic with integrals. I sometimes wondered and
never bothered myself as to how decimals were represented as binaries.
I want to understand your example.

I can see a pattern in the representation.

0.1 is half.
0.01 is a right shift and you further halve it.
0.001 two right shifts further halving it and so on.

You lost me at 0.011. Can I please request you to explain.


Mu *************** @ yahoo.com 说:


< snip>
Mu***************@yahoo.com said:

<snip>

我知道带积分的二进制算术。我有时想知道并且

从未打扰过我自己如何将小数表示为二进制文件。
I know binary arithmetic with integrals. I sometimes wondered and
never bothered myself as to how decimals were represented as binaries.



浮点数的表示是实现定义的。

IEEE 754很常见但不通用。

The representation of floating-point numbers is implementation-defined.
IEEE 754 is common but not universal.


我想了解你的例子。


我可以看到代表中的模式。


0.1是一半。

0.01是一个右移,你进一步减半。

0.001两个右移进一步减半等等。


你在0.011失去了我。我可以请你解释一下。
I want to understand your example.

I can see a pattern in the representation.

0.1 is half.
0.01 is a right shift and you further halve it.
0.001 two right shifts further halving it and so on.

You lost me at 0.011. Can I please request you to explain.



您理解二进制整数。扩展概念。


二进制的13是1101(1 * 8 + 1 * 4 + 0 * 2 + 1 * 1)。


因此,每列代表一个乘数的一半,就像它左边的列

那样。


所以我们可以合理地想到二进制之外的列指向

代表一半,四分之一,八分之一等等。


所以0.11将是(半个+四分之一)=(四分之三)= 0.75


0.011将是(季度+第八)=(三分之八)= 0.375


等等。


当然,这并不一定是它们在内部存储的方式,但它确实可以让你很好地了解存储a所需的位数

特定精度的特定值。我建议您阅读
http:// docs .sun.com / source / 806-3568 / ncg_goldberg.html


(标题:每个计算机科学家应该知道什么关于浮点数

Arithmetic)


-

Richard Heathfield

Usenet是一个奇怪的地方 - dmr 29/7/1999
http://www.cpax.org.uk

电子邮件:rjh在上述域名中, - www。

You understand binary integers. Extend the concept.

13 in binary is 1101 (1 * eight + 1 * four + 0 * two + 1 * one).

So each column represents a multiplier half as big as that of the column
to its left.

So we might reasonably think of the columns beyond the binary point as
representing a half, a quarter, an eighth, etc.

So 0.11 would be (half + quarter) = (three-quarters) = 0.75

0.011 would be (quarter + eighth) = (three-eighths) = 0.375

and so on.

That isn''t necessarily how they''re stored internally, of course, but it
does give you a good idea of the number of bits you need for storing a
particular value to a particular precision. I recommend that you read
http://docs.sun.com/source/806-3568/ncg_goldberg.html

(Title: "What Every Computer Scientist Should Know About Floating-Point
Arithmetic")

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.


这篇关于浮点舍入错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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