来自 stdint.h 的快速类型的溢出行为
Overflow behaviour of fast types from stdint.h
C99 和 C++11(以及之前的 POSIX)在 stdint
header 中引入了 least
和 fast
类型,例如int_fast16_t
或 uint_fast8_t
.
我想知道这些类型的溢出行为有什么保证。如果这些与 "normal" 整数类型相同(以便无符号类型在溢出时回绕),我想知道 uint_fast8_t
实际上如何映射到与 fixed-witdh uint8_t
类型,因此速度更快。
溢出规则与任何 signed/unsigned 整数变量相同。
uint_fast16_t
映射到至少 16 位的最快大小。如果平台上最快的大小恰好是 32 位,则行为会有所不同。考虑:
uint_fast16_t k = 1 << 16;
if (k == 0) {
printf("k is 16 bits\n");
} else {
printf("k is larger than 16 bits\n");
}
If these are the same as for "normal" integer types (so that unsigned types wrap around on overflow)
保障完全一样。有符号整数会溢出,无符号整数会回绕。可以表示的最大值取决于该类型是哪个整数类型的别名。
I wonder how uint_fast8_t can actually be mapped to any different type than the fixed-witdh uint8_t type
它可以是至少 8 位宽的任何无符号整数类型的别名。
C11 n1570 表示
The typedef name
int_fastN_t
designates the fastest signed integer type with a width
of at least
N
. The typedef name
uint_fastN_t
designates the fastest unsigned integer
type with a width of at least
N
.
因此不能保证任何行为;这些说的是 int_fastN_t
不能在 2^(n-1) - 1
... 2^(n-1) - 1
范围内有符号溢出; uint_fastN_t
不得对小于 2^n - 1
的值进行环绕。如果你需要更精确的环绕行为,那么不要使用快速类型,而是使用精确宽度类型(又名 intN_t
和 uintN_t
)。
I wonder how uint_fast8_t
can actually be mapped to any different type than the fixed-width uint8_t
type, and thus be faster.
首先,不必 是 uint8_t
类型。在 36 位字寻址机器上(它们已经存在),char
可能是 9 位宽。 (Word addressed 意味着访问内存的自然方式是 words(某种大小)。寻址一个字的子部分需要移位和掩码和寻址此类子部分的指针需要额外的位来指代字内的子单元。)
在这样的机器上,编译器作者会有一个有趣的决定,即是使 uint_fast8_t
与 unsigned char
(9 位)相同还是 36 位 unsigned int
类型。
正如其他人所说,将有一个实现定义这些类型的最大值,如果超过该限制,无符号类型将换行,而有符号类型将导致未定义的行为。
C99 和 C++11(以及之前的 POSIX)在 stdint
header 中引入了 least
和 fast
类型,例如int_fast16_t
或 uint_fast8_t
.
我想知道这些类型的溢出行为有什么保证。如果这些与 "normal" 整数类型相同(以便无符号类型在溢出时回绕),我想知道 uint_fast8_t
实际上如何映射到与 fixed-witdh uint8_t
类型,因此速度更快。
溢出规则与任何 signed/unsigned 整数变量相同。
uint_fast16_t
映射到至少 16 位的最快大小。如果平台上最快的大小恰好是 32 位,则行为会有所不同。考虑:
uint_fast16_t k = 1 << 16;
if (k == 0) {
printf("k is 16 bits\n");
} else {
printf("k is larger than 16 bits\n");
}
If these are the same as for "normal" integer types (so that unsigned types wrap around on overflow)
保障完全一样。有符号整数会溢出,无符号整数会回绕。可以表示的最大值取决于该类型是哪个整数类型的别名。
I wonder how uint_fast8_t can actually be mapped to any different type than the fixed-witdh uint8_t type
它可以是至少 8 位宽的任何无符号整数类型的别名。
C11 n1570 表示
The typedef name
int_fastN_t
designates the fastest signed integer type with a width of at least N . The typedef nameuint_fastN_t
designates the fastest unsigned integer type with a width of at least N .
因此不能保证任何行为;这些说的是 int_fastN_t
不能在 2^(n-1) - 1
... 2^(n-1) - 1
范围内有符号溢出; uint_fastN_t
不得对小于 2^n - 1
的值进行环绕。如果你需要更精确的环绕行为,那么不要使用快速类型,而是使用精确宽度类型(又名 intN_t
和 uintN_t
)。
I wonder how
uint_fast8_t
can actually be mapped to any different type than the fixed-widthuint8_t
type, and thus be faster.
首先,不必 是 uint8_t
类型。在 36 位字寻址机器上(它们已经存在),char
可能是 9 位宽。 (Word addressed 意味着访问内存的自然方式是 words(某种大小)。寻址一个字的子部分需要移位和掩码和寻址此类子部分的指针需要额外的位来指代字内的子单元。)
在这样的机器上,编译器作者会有一个有趣的决定,即是使 uint_fast8_t
与 unsigned char
(9 位)相同还是 36 位 unsigned int
类型。
正如其他人所说,将有一个实现定义这些类型的最大值,如果超过该限制,无符号类型将换行,而有符号类型将导致未定义的行为。