为什么std::bit_width为值0返回0,它不应该返回1吗?

std::bit_width发现代表整数所需的最小比特x作为1+floor(log(x))

为什么std::bit_width值 0 返回 0?它不应该返回 1,因为表示 0 所需的位数是 1?

另外,我认为1公式中的 是一个偏移量。

回答

有一段奇怪的历史bit_width

最终将被称为bit_width开始生命的函数log2,作为添加整数二次函数的提议的一部分。log2指定为在传递 0 时生成 UB。

因为这就是对数的工作原理。

但随后,事情发生了变化。该函数后来变成了log2p1,并且由于未指定的原因被赋予了更广泛的契约(C++ 术语中的“广泛契约”意味着更多的东西被认为是有效的输入)。具体来说,0 是有效输入,并产生 0 值。

不是对数的工作方式,但无论如何。

随着 C++20 接近标准化,发现了名称冲突 (PDF)。该名称log2p1恰好对应于 IEEE-754 算法的名称,但它完全不同。此外,具有类似输入和结果的其他语言中的函数使用类似bit_length. 所以改名为bit_width.

而且由于它不再假装做对数,0 处的行为可以是我们想要的任何东西。

实际上,Python 函数int.bit_length具有完全相同的行为。前导零不被视为位长度的一部分,并且由于 的​​值0包含所有前导零......

  • The function formerly known as `log2p1` actually does work exactly like a logarithm; the issue is that the formula it evaluates is not `floor(log(n) + 1)` but `ceil(log(n + 1))`. Why the committee did not describe it using the second formula, which works for all `n`, but instead used the first one which has an awkward discontinuity at `n=0` and therefore needs to be described more wordily, is anyone's guess (this is the *C++* standard committee we're talking about, after all).
  • @psmears: "*including having effects way outside the return value of this function*" That's what happens when you take the logarithm of 0 as well. It is a thing you cannot do, and if you do it, then your math is broken and ceases to be actual math.
  • It's perfectly valid (and useful) in mathematics to [extend the real number line](https://en.wikipedia.org/wiki/Extended_real_number_line) to include plus/minus infinity, and to define log 0 to be minus infinity. Or to treat log as a [partial function](https://en.wikipedia.org/wiki/Partial_function) on the reals. This answer currently says "that is _not_ how logarithms work" about a behavior that is 100% conformant with the part you describe as "that _is_ how logarithms work", which seems a bit inconsistent 🙂
  • @psmears so what's tan 90

回答

因为在数学上它是有道理的:

bit_width(x) = log2(round_up_to_nearest_integer_power_of_2(x + 1))
bit_width(0) = log2(round_up_to_nearest_integer_power_of_2(0 + 1))
             = log2(1)
             = 0


回答

详细说明评论中的内容:

假设“位宽”意味着“存储(非负整数)数所需的最少位数”。直观地说,我们至少需要log2(n)四舍五入的位,所以它是一个接近 的公式ceil(log2(n)),所以 255 需要ceil(log2(255)) = ceil(7.99..) = 8位,但这不适用于 2 的幂,所以我们可以添加一个 1 的模糊因子n来得到ceil(log2(n+1))。这恰好在数学上等同1+floor(log2(n))于正 n,但log2(0)没有定义或定义为无用的东西,如地板版本中的负无穷大。

如果我们使用 0 的上限公式,我们会得到结果。您还可以看到我没有写出前导零,正如 Nicol Bolas 指出的那样,0 都是前导零。

n 箱(n) 位宽(n)
8 1000 4
7 111 3
6 110 3
5 101 3
4 100 3
3 11 2
2 10 2
1 1 1
0 0

以上是为什么std::bit_width为值0返回0,它不应该返回1吗?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>