std::numeric_limits<T>::d igits 应该代表什么?
What is std::numeric_limits<T>::digits supposed to represent?
我正在编写一个类似整数的类,它表示位于某个范围内的值。例如,bounded::integer<0, 10>
的值在 [0, 10] 范围内。对于这个类,我定义了radix
2
。
digits
对bounded::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 位数字(因为 0
和 1
不在范围内),并且根据 18.3.2.7.1:
所有成员均应具备所有专业。但是,许多值仅要求在某些条件下有意义(例如,
epsilon()
仅在false
is_integer
时才有意义)。任何不"有意义"的值都应设置为 0 或 false。
我相信任何没有0
作为可能值的类似整数的类都无法有意义地计算digits
和digits10
。
另一个可能的答案是使用数字的信息论定义。但是,这与内置整数的值不一致。描述明确省略了符号位,但这些仍然被视为单一信息位,所以我觉得排除了这种解释。似乎这种对符号位的排除也意味着我必须取第一个数字范围的负端和正端的较小幅度,这就是为什么我认为第一个问题等同于bounded::integer<0, 5>
。这是因为您只能保证可以存储 2 位而不会丢失数据。只要您的数字为负数,您最多可以存储 6 位,但一般来说,您只能存储 2 位。
bounded::integer<16, 19>
要棘手得多,但我相信对"没有意义"的解释比将值转移过来并给出与bounded::integer<0, 3>
相同的答案更有意义,这将是2
。
我相信这种解释遵循标准,与其他整数类型一致,并且最不可能混淆此类的用户。
为了回答digits
用例的问题,一位评论者提到了基数排序。以 2 为基数的排序可能希望使用 digits
中的值对数字进行排序。如果您将digits
设置为 0
,那就好了,因为这表示尝试使用这种基数排序的错误条件,但是我们可以在仍然与内置类型保持一致的同时做得更好吗?
对于无符号整数,取决于 digits
值的基数排序工作得很好。 uint8_t
有digits == 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]
,这样您就不必担心符号位等。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- ifstream什么都没读
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 我应该使用什么来代替void作为变体中的替代类型之一
- std::numeric_limits<T>::d igits 应该代表什么?