std::numeric_limits<T>::d igits 应该代表什么?

What is std::numeric_limits<T>::digits supposed to represent?

本文关键字:什么 igits numeric limits lt gt std      更新时间:2023-10-16

我正在编写一个类似整数的类,它表示位于某个范围内的值。例如,bounded::integer<0, 10>的值在 [0, 10] 范围内。对于这个类,我定义了radix 2

digitsbounded::integer<-100, 5>的价值应该是多少?

bounded::integer<16, 19>呢?

在多看了一下标准并思考之后,我相信我有最好的答案,但我不确定。

首先,digits的定义取自最新的C++14标准草案N3797,§18.3.2.4:

static constexpr int digits;

8 无需更改即可表示的radix位数。

9 对于整数类型,表示中无符号位的数目。

10 对于浮点类型,尾数中的radix位数

bounded::integer<-100, 5>的情况与 bounded::integer<0, 5> 的情况相同,这将给出 2 的值。

对于bounded::integer<16, 19>的情况,digits应该定义为0。这样的类甚至不能表示 1 位数字(因为 01 不在范围内),并且根据 18.3.2.7.1:

所有

成员均应具备所有专业。但是,许多值仅要求在某些条件下有意义(例如,epsilon()仅在false is_integer时才有意义)。任何不"有意义"的值都应设置为 0 或 false。

我相信任何没有0作为可能值的类似整数的类都无法有意义地计算digitsdigits10

另一个可能的答案是使用数字的信息论定义。但是,这与内置整数的值不一致。描述明确省略了符号位,但这些仍然被视为单一信息位,所以我觉得排除了这种解释。似乎这种对符号位的排除也意味着我必须取第一个数字范围的负端和正端的较小幅度,这就是为什么我认为第一个问题等同于bounded::integer<0, 5>。这是因为您只能保证可以存储 2 位而不会丢失数据。只要您的数字为负数,您最多可以存储 6 位,但一般来说,您只能存储 2 位。

bounded::integer<16, 19>要棘手得多,但我相信对"没有意义"的解释比将值转移过来并给出与bounded::integer<0, 3>相同的答案更有意义,这将是2

我相信这种解释遵循标准,与其他整数类型一致,并且最不可能混淆此类的用户。

为了回答digits用例的问题,一位评论者提到了基数排序。以 2 为基数的排序可能希望使用 digits 中的值对数字进行排序。如果您将digits设置为 0 ,那就好了,因为这表示尝试使用这种基数排序的错误条件,但是我们可以在仍然与内置类型保持一致的同时做得更好吗?

对于无符号整数,取决于 digits 值的基数排序工作得很好。 uint8_tdigits == 8.但是,对于有符号整数,这不起作用:std::numeric_limits<int8_t>::digits == 7 .您还需要对该符号位进行排序,但digits没有为您提供足够的信息来执行此操作。

你想多了。有两个简单的选项可用于digits您自己的专业ranged_integer

  • log2(Last-First)表示范围[First, Last)
  • N * numeric_limits<U>::digits的值,对应于可以存储范围的最小基础存储std::array<U, N>

请注意,您的类ranged_integer可以在内部进行转换以映射一系列,例如 [-100, 5] [0, 105],这样您就不必担心符号位等。