如何重现 C++双舍入问题
浮点精度在 C++
中受到限制,对于新手程序员来说,在舍入值时常常会造成麻烦。
在教授学生时,演示浮点精度数字舍入问题通常很有用。您知道哪些可能的方法可以在所有 C++
编译器上一致地演示此类舍入问题?
Floating point precision is limited in C++
and for novice programmers that often causes trouble when rounding values.
When teaching students it is often useful to demonstrate the floating point precision number rounding issue. What possible ways do you know to demonstrate such rounding issue consistently on all C++
compilers?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以使用以下示例:
程序永远不会终止,因为 d 永远不等于 1。
You can use this example:
The program will never terminate as d never equals 1.
首先,我们应该注意到,在IEEE754浮点中,
1.5
、0.5
和2.0
都是精确表示的。因此,在这个具体示例中,1.5
永远不会是1.499999999999
。话虽如此,我认为要做的事情是让你的学生接触到不能完全可表示的数字。比如说,
1.1
。这是一个示例程序:
也许您可以引导他们完成这个程序,请小心地说
d1
和d2
都大约等于 1.1 。对于高级学生,您可以通过派系二进制算术来了解为什么
1/2
可以表示,但1/10
则不能。编辑:我认为阐明这一点的方法是将重复的十进制分数与重复的二进制分数进行比较。以十进制显示您的学生
1/7
。在黑板上做长除法。指出您无法使用有限的资源精确地写出1/7
。然后,要么向他们展示如何将1/10
写为二进制分数,要么只是告诉他们您无法使用有限的资源写下它。指出浮点数是有限的(32 位),双精度数是有限的(64 位)。也许引入鸽子原理并说你不能用有限的字长表示无限集(像所有有理数一样)。
无论您尝试什么,请返回此处报告并让我们知道它是如何工作的。
First, we should note that, in IEEE754 floating point,
1.5
,0.5
, and2.0
are all exactly represented. So, in this specific example,1.5
will never be1.499999999999
.Having said that, I think the thing to do is to expose your students to numbers are not exactly representable. Say,
1.1
.Here is a sample program:
Perhaps you can walk them through this program, being careful to say that
d1
andd2
are both approximately equal to 1.1.For advanced students, you can go through factional binary arithmetic and see why
1/2
is representable, but1/10
is not.EDIT: I think the way to bring the point home is to compare repeating decimal fractions with repeating binary fractions. Show your students
1/7
in decimal. Do the long division on the board. Point out that you cannot write1/7
down exactly using finite resources. Then, either show them how to write1/10
as a binary fraction, or just tell them that you can't write down it either using finite resources.Point out that floats are finite (32 bits) and doubles are finite (64 bits). Maybe introduce pigeonhole principal and say that you can't represent an infinite set (like all rationals) in a finite word length.
Whatever you try, please report back here and let us know how it works.
我喜欢下面的例子:
输出如下:
矛盾的原因是浮点计算。
I like the following example:
The output follows:
The cause of contradiction is floating point calculations.
或者
:)
or
:)
试试这个例子:
它打印出
note that 0.075 四舍五入到小数点后两位应该是 0.08,而不是我们在输出中看到的 0.07。这个例子清楚地展示了双重舍入问题
Try this example:
which prints
note that 0.075 rounded to two decimal places should be 0.08, not 0.07 as we see in the output. This example clearly demonstrates double rounding issue