浮点舍入错误 [英] Floating point rounding error
问题描述
为什么浮点有舍入误差?如何解决这个问题?
例如,以下内容:
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屋!