简体   繁体   English

为什么浮点尾数的位宽表示的数字是整数的两倍?

[英]Why does the bit-width of the mantissa of a floating point represent twice as many numbers compared to an int?

I am told that a double in C++ has a mantissa that is capable of safely and accurately representing [-(2 53 − 1), 2 53 − 1] integers.有人告诉我,C++ 中的double具有能够安全准确地表示 [-(2 53 − 1), 2 53 − 1] 整数的尾数。

How is this possible when the mantissa is only 52 bits?当尾数只有 52 位时,这怎么可能? Why is it that an int16 is only capable of having a range of [-32,768, +32,767], or [-2 15 , 2 15 -1], when the same thing could be used for int16 to allow twice as many representable numbers?为什么int16只能具有 [-32,768, +32,767] 或 [-2 15 , 2 15 -1] 的范围,而int16可以使用相同的东西来允许两倍的可表示数字?

The format of the double (64 bits) is as follows: double (64 位)的格式如下:

1 bit: sign
11 bits: exponent
52 bits: mantissa

We only need to look at the positive integers we can represent with the mantissa, since the sign bit takes care of the negative integers for us.我们只需要查看可以用尾数表示的正整数,因为符号位会为我们处理负整数。

Naively, with 52 bits, we can store unsigned integers from 0 to 2^52 - 1. With a sign bit, this lets us store from -2^52 - 1 to 2^52 - 1 .天真地,使用 52 位,我们可以存储从 0 到 2^52 - 1 的无符号整数。使用符号位,我们可以存储从-2^52 - 12^52 - 1的整数。

However, we have a little trick we can use.但是,我们有一个可以使用的小技巧。 We say that the first digit of our integer is always a 1, which gives us an extra bit to work with.我们说我们的 integer 的第一个数字始终是 1,这给了我们一个额外的工作位。

To see why this works, let's dig a little deeper.要了解为什么会这样,让我们更深入地挖掘一下。

Every positive integer will have at least one 1 in its binary representation.每个正数 integer 在其二进制表示中至少有一个1 So, we shift the mantissa left or right until we get a 1 at the start, using the exponent.因此,我们使用指数向左或向右移动尾数,直到我们在开始时得到 1。 An example might help here:一个例子在这里可能会有所帮助:

9, represented as an unsigned int: 000...0001001 (dots representing more 0 s). 9,表示为无符号整数: 000...0001001 (点代表更多的0 s)。

Written another way: 1.001 * 2^3 .另一种写法: 1.001 * 2^3 ( 1.001 being in binary, not decimal.) 1.001是二进制,而不是十进制。)

And, we'll agree to never use a 0 as the first bit.而且,我们同意永远不要使用 0 作为第一位。 So even though we could write 9 as 0.1001 * 2^4 or 0.01001 * 2^5 , we won't.因此,即使我们可以将 9 写为0.1001 * 2^40.01001 * 2^5 ,我们也不会。 We'll agree that when we write the numbers out in this format, we'll always make sure we use the exponent to "shift" bits over until we start with a 1 .我们会同意,当我们以这种格式写出数字时,我们将始终确保使用指数“移位”位,直到我们以1开头。

So, the information we need to store to get 9 is as follows:所以,我们需要存储得到9的信息如下:

e: 3
i: 1.001

But if i always starts with 1 , why bother writing it out every time?但是如果i总是从1开始,为什么每次都写出来呢? Let's just keep the following instead:让我们保留以下内容:

e: 3
i: 001

Using precisely this information, we can reconstruct the number as: 1.i * 2^e == 9 .正是使用这些信息,我们可以将数字重构为: 1.i * 2^e == 9

When we get up to larger numbers, our " i " will be bigger, maybe up to 52 bits used, but we're actually storing 53 bits of information because of the leading 1 we always have.当我们得到更大的数字时,我们的“ i ”会更大,可能最多使用 52 位,但我们实际上存储了53位信息,因为我们总是有前导1

Final Note: This is not quite what is stored in the exponent and mantissa of a double, I've simplified things to help explain, but hopefully this helps people understand where the missing bit is from.最后说明:这不是存储在双精度数的指数和尾数中的内容,我已经简化了一些事情来帮助解释,但希望这有助于人们理解缺失位的来源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM