为什么 0.1f 的最后一个二进制位四舍五入为 1?
我正在大学学习操作系统课程,我们最近学习了浮点数在内存中的表示方式。
我们的作业是关于手动将浮点数(float
s)转换为其二进制表示形式。
例如,经过长时间的转换过程后,200,0234375
将给出01000011010010000000011000000000
。
问题之一是如何在内存中表示 0.1f。所以我完成了整个转换过程,最终得到了这个:
00111101110011001100110011001100
就目前为止我们所学到的,这就是问题的正确答案(我问老师)。
但是,在下一个问题上,我们被要求用程序验证答案,以查看 0.1f 的实际二进制表示。真实的表述是这样的:
00111101110011001100110011001101
(注意最后一位)
然后我们被要求尝试猜测为什么会发生这种情况。
我在转换数字时注意到周期性的 0011
,并且由于最终 0
之后的下一位将是 1
,我假设计算机将最后的 0
舍入 到 1
,这可以解释差异。
所以,我想知道的是,我的说法正确吗? 计算机是否会根据使用 23 位尾数时的下一位来舍入最后一位?
这是一项家庭作业,所以如果您能简单地引导我找到答案如果我错了,我将不胜感激。
此外,我无法通过谷歌搜索我能想到的关键字找到我的问题的答案。如果这是重复的,请原谅我。
I'm following an operating system course at college and we recently learned how floating point numbers are represented in memory.
Our homework is about converting floating numbers(float
s) to their binary representations by hand.
e.g. 200,0234375
would give 01000011010010000000011000000000
after the long conversion process.
One of the questions is about how 0.1f would be represented in memory. So I did the whole conversion process and I ended up with this:
00111101110011001100110011001100
With what we've learned so far, this is the correct answer to the question (I asked the teacher).
But, on the next question, we are asked to verify the answer with a program to see the actual binary representation of 0.1f. The real representation is this:
00111101110011001100110011001101
(Notice the last bit)
We are then asked to try to guess why this is happening.
I noticed the periodic 0011
while converting the number and since the next bit after the final 0
would be a 1
, I would assume that the computer would round that final 0
to a 1
, which would explain the difference.
So, what I want to know is, am I correct? Is the computer rounding the last bit based on what would be the next bit when the 23 bits of the mantissa are used?
This is a homework, so if you could simply guide me towards the answer if I'm wrong I would appreciate.
Also, I couldn't find the answer to my question by Googling with the keywords I could think of. Pardon me if this is a duplicate.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的当然。默认情况下,编译器和浮点运算系统会尝试为您提供正确的舍入结果。
打个比方,如果我让你把 2/3 写到小数点后三位,你会回答 0.666 还是 0.667?它应该是 0.667,因为它更接近真实答案。
Yes, of course. By default, the compiler and the floating-point arithmetic system tries to give you correctly rounded results.
As an analogy, if I asked you to write 2/3 to three decimal places, would you answer with 0.666 or 0.667? It should be 0.667, because it's closer to the true answer.
我不太确定如何在不在这里给出答案的情况下指导您,但是是的,您已经明白了。 IEEE 标准包含针对此类舍入的具体规定。查找守卫、圆形和粘性位。
I am not quite sure how to guide you without just giving the answer here, but yes, you're on to it. The IEEE standard includes specific provisions for this kind of rounding. Look up guard, round, and sticky bits.
这取决于您的平台、特定的浮点硬件以及该硬件上的特定设置。
特别是,在 x86 平台上,特定行为将取决于 FPU 或 SSE 控制字寄存器的内容。
This will depend on your platform, the particular floating point hardware, and the particular settings on that hardware.
In particular, on x86 platforms, the particular behavior will depend on the contents of the FPU or SSE Control Word registers.
有多种舍入模式。
您可以在维基百科中阅读相关内容。
这只是一个实施问题。 C++ 没有这方面的标准。
There are several rounding modes.
You can read about it in wikipedia.
It's just a matter of implementation. C++ doesn't have a standard for that.