类型定义 表示可以包含size_t的有符号类型
typedef for a signed type that can contain a size_t?
是否有可以包含完整范围的size_t
值的有符号类型的标准(或 MSVC 专有)typedef? 即在 64 位系统上,它将是一个 128 位有符号整数。
定义这样的类型。实现使size_t
成为最大的受支持无符号类型是完全合法的,这将(几乎肯定)意味着没有有符号类型可以保存其所有值。
ptrdiff_t
不一定足够宽。这是减去两个指针的结果,但没有任何东西说指针减法不能溢出。请参阅C++标准的第5.7节:
当减去指向同一数组对象的元素的两个指针时,结果是两个数组的下标的差异元素。结果的类型是实现定义的签名整体式;此类型应与定义为
std::ptrdiff_t
在<cstddef>
标头 (18.2) 中。与任何其他算术溢出,如果结果不适合提供的空间,行为未定义。
最大的有符号类型是 intmax_t
,以 <stdint.h>
或 <cstdint>
定义。这是一个 C99 功能,C++11 是第一个包含 C99 标准库的C++标准,因此您的编译器可能不支持它(MSVC 很可能不支持)。(9年后:这不再是一个大问题。如果有一个足够宽的有符号类型来容纳类型 size_t
的所有可能值,那么intmax_t
是(尽管可能有一个更窄的有符号类型也符合条件)。
您也可以使用 long long
,这是一种有符号类型,保证至少为 64 位(并且很可能与 intmax_t
相同)。即使它不够宽,无法容纳所有可能的 size_t
类型的值,它几乎肯定会容纳 size_t
类型的所有相关值——除非你的实现实际上支持大于 8 EB(即 8192 PB,或 8388608 TB)的对象。
(注意,我使用的是"exa-","peta-"和"tera-"的二进制定义,其有效性值得怀疑。
如果你想要一个可以包含系统最大值的标准类型,也许<cstdint>
(自 C++11 以来)会有所帮助。
该标头中有一个 typedef,其中包含最大宽度整数类型,类型为 intmax_t
。有符号整数的intmax_t
和无符号整数的uintmax_t
是体系结构完全支持的最大整数。
因此,假设您处于 64 位体系结构中,以下说明:
std::cout << "intmax_t is same int64_t? "
<< (std::is_same<intmax_t, int64_t>::value ? "Yes" : "No");
将输出:
intmax_t int64_t一样?是的
现场演示。
希望对您有所帮助。
我假设你需要这种类型的某种指针算术。除了std::ptrdiff_t
之外,您不太可能需要任何其他东西.这在现代计算机上发挥作用的唯一情况是当您处于 32 位模式并且您正在处理超过 2^31 字节的数据集时。(如果没有特殊工作,这在Windows上甚至是不可能的。您将无法同时使用该大小的两个数组。在这种情况下,您可能无论如何都应该在 64 位模式下工作。
在 64 位模式下,以目前的内存开发速度,在未来 40 年左右的时间里,它很可能不会成为问题。当它成为问题时,然后在 128 位模式下编译您的代码,它将继续运行。;)
如果你想要一个可以将std::size_t
的每个值都保存为正值的有符号类型,我不知道有什么办法。假设您有相同数量的位,则存储符号需要一位信息,因此新的最大值是旧值的一半。另一方面,使用该位的值的上半部分只是包装在负数中,因此您始终可以投射回去。
实际上,您可能需要的是将高无符号/负符号值与其他值分开,无论您在哪里铸造它们。如果 unsigned 0 <= x < M/2 <= y <= M
映射到 0 <= (x, y & (M/2)) < M/2
,则每个值都被考虑在内,但不会在任一方向上换行为 x 或 y。如果签名-M/2 <= y < 0 <= x < M/2
映射到0 <= (x, y+M/2) < M
,则相同。
这样,您知道何时x < 0
或y > M/2
转换回来超出了范围,但与此同时,您可以进行比较,例如无符号y(M) < y(M)+1
或通常在包装后失败的有符号x(0) > x(0)-1
,例如0 < -1 = M
,M > M+1 = 0
等。
作为记录,我认为最好计算std::size_t
对应的符号类型,std::make_signed_t<std::size_t>
.目前它很可能long long
来自unsigned long long
,但我不知道这有多普遍,或者它是否会改变。我建议使用那里的std::numeric_limits<T>
来检查最小值/最大值。
- 将超出范围的整数分配给有符号字符类型
- C ++中无符号位长度类型之间的隐式转换,即uint8_t,uint16_t
- 类型的大小与无符号的等效项?
- 整数类型应该显式转换(例如"int"到"无符号")还是只会增加混乱?
- 应用于无符号类型的一元减号运算符
- 为什么 Clang 和 GCC 中两个无符号整数之和的结果类型不同
- 提升不良词法强制转换:将字符串转换为无符号长整型时,无法将源类型值解释为目标
- 在有符号基础类型枚举的位域上溢出
- C++,概念不适用于无符号整数作为结果类型?
- 函数指针给我"重新声明为不同类型的符号"错误
- 为什么 (-i) 的类型(其中 i 是无符号的 int)仍然是无符号的 int?
- 无符号长整型和无符号 int 之间有什么区别,这 2 种类型应该如何在 c# 中封送?
- 这种错误的原因是什么:将"功能"重新定义为不同类型的符号
- 为什么C++数组索引值是有符号的,而不是围绕size_t类型构建的(或者我错了)
- 什么是 16 字节有符号整数数据类型?
- 无符号类型和C++
- C++和无符号类型
- 运行时错误:有符号整数溢出:964632435 * 10 无法在类型 'int' 中表示
- 在 c++ 中将结构类型转换为无符号字符*
- 重写基于模板类型符号的虚拟方法