如果我将负值赋给 unsigned char 会发生什么?
What will happen if I assign negative value to an unsigned char?
在 C++ primer 中它说 "if we assign an out of range value to an object of unsigned type the result is the remainder of the value modulo the number of values the target type can hold."
给出了例子:
int main(){
unsigned char i = -1;
// As per the book the value of i is 255 .
}
任何人都可以向我解释一下这是如何工作的。
用 Stroustrup 的话来说:
If the destination type is unsigned
, the resulting value is simply as many bits from the source as will fit in the destination (high-order bits are thrown away if necessary). More precisely, the result is the least unsigned integer congruent to the source integer modulo 2 to the nth, where n is the number of bits used to represent the unsigned type.
摘自 C++ 标准 N3936:
For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned
integer type: “unsigned char”, “unsigned short int”, “unsigned int”, “unsigned long int”,
and “unsigned long long int”, each of which occupies the same amount of storage and has the same
alignment requirements (3.11) as the corresponding signed integer type47; that is, each signed integer type
has the same object representation as its corresponding unsigned integer type.
文字 1
的类型为 int
。对于此解释,我们假设 sizeof(int) == 4
很可能是这样。那么二进制的 1
看起来像这样:
00000000 00000000 00000000 00000001
现在让我们应用一元减运算符来得到 -1
。我们假设 two's complement 最有可能被使用(查看 two's complement 以获得更多解释)。我们得到:
11111111 11111111 11111111 11111111
请注意,在上面的数字中,第一位是符号位。
当您尝试将此数字分配给 unsigned char
时,其中包含 sizeof(unsigned char) == 1
,该值将被截断为:
11111111
现在,如果将其转换为十进制,您将得到 255
。这里第一位不被视为符号位,因为类型是 unsigned
.
the result is the remainder of the value modulo the number of values the target type can hold
从“目标类型可以容纳的值的数量”开始。对于 unsigned char
,这是什么?范围是从 0 到 255(含),因此总共可以表示(或“保留”)256 个值。
一般来说,可以用特定的无符号整数表示法表示的值的数量由 2n 给出,其中 n是用于存储该类型的位数。
一个unsigned char
是一个8位类型,所以28 == 256,正如我们已经知道的那样。
现在,我们需要执行取模运算。在将 -1 分配给 unsigned char
的情况下,您将得到 -1 MOD 256 == 255
.
一般来说,公式是:x MOD 2n,其中 x 是您尝试的值分配,n 是您要分配的类型的位宽。
更正式地说,这是 C++11 语言标准 (§ 3.9.1/4) 中的规定。它说:
Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.*
* This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.
也许考虑模运算(以及您最常看到的描述)的一种更简单的方法是上溢和下溢环绕。您从 -1 开始,它超出了 unsigned char
的范围(即 0–255),因此它环绕到最大可表示值(即 255)。
它在 C 中等同于 C++,尽管措辞不同:
6.3.1.3 Signed and unsigned integers
1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented by the new type until the value is in the range of the new type.
3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
我自己正在阅读 C++ primer 的摘录,我认为我已经想出了一种方法来从数学上弄清楚这些值是如何产生的(如果我错了,请随时纠正我:)) .以下面的特定代码为例。
unsigned char c = -4489;
std::cout << +c << std::endl; // will yield 119 as its output
那么119的这个答案是怎么出来的呢?
我们将 4489 除以字符总数,即 2^8 = 256,余数为 137。
4489 % 256 = 137.
现在只需从 256 中减去 137。
256 - 137 = 119.
这就是我们简单导出 mod 值的方式。也请自己尝试其他值。对我来说非常准确!
在 C++ primer 中它说 "if we assign an out of range value to an object of unsigned type the result is the remainder of the value modulo the number of values the target type can hold."
给出了例子:
int main(){
unsigned char i = -1;
// As per the book the value of i is 255 .
}
任何人都可以向我解释一下这是如何工作的。
用 Stroustrup 的话来说:
If the destination type is
unsigned
, the resulting value is simply as many bits from the source as will fit in the destination (high-order bits are thrown away if necessary). More precisely, the result is the least unsigned integer congruent to the source integer modulo 2 to the nth, where n is the number of bits used to represent the unsigned type.
摘自 C++ 标准 N3936:
For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: “unsigned char”, “unsigned short int”, “unsigned int”, “unsigned long int”, and “unsigned long long int”, each of which occupies the same amount of storage and has the same alignment requirements (3.11) as the corresponding signed integer type47; that is, each signed integer type has the same object representation as its corresponding unsigned integer type.
文字 1
的类型为 int
。对于此解释,我们假设 sizeof(int) == 4
很可能是这样。那么二进制的 1
看起来像这样:
00000000 00000000 00000000 00000001
现在让我们应用一元减运算符来得到 -1
。我们假设 two's complement 最有可能被使用(查看 two's complement 以获得更多解释)。我们得到:
11111111 11111111 11111111 11111111
请注意,在上面的数字中,第一位是符号位。
当您尝试将此数字分配给 unsigned char
时,其中包含 sizeof(unsigned char) == 1
,该值将被截断为:
11111111
现在,如果将其转换为十进制,您将得到 255
。这里第一位不被视为符号位,因为类型是 unsigned
.
the result is the remainder of the value modulo the number of values the target type can hold
从“目标类型可以容纳的值的数量”开始。对于 unsigned char
,这是什么?范围是从 0 到 255(含),因此总共可以表示(或“保留”)256 个值。
一般来说,可以用特定的无符号整数表示法表示的值的数量由 2n 给出,其中 n是用于存储该类型的位数。
一个unsigned char
是一个8位类型,所以28 == 256,正如我们已经知道的那样。
现在,我们需要执行取模运算。在将 -1 分配给 unsigned char
的情况下,您将得到 -1 MOD 256 == 255
.
一般来说,公式是:x MOD 2n,其中 x 是您尝试的值分配,n 是您要分配的类型的位宽。
更正式地说,这是 C++11 语言标准 (§ 3.9.1/4) 中的规定。它说:
Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.*
* This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.
也许考虑模运算(以及您最常看到的描述)的一种更简单的方法是上溢和下溢环绕。您从 -1 开始,它超出了 unsigned char
的范围(即 0–255),因此它环绕到最大可表示值(即 255)。
它在 C 中等同于 C++,尽管措辞不同:
6.3.1.3 Signed and unsigned integers
1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented by the new type until the value is in the range of the new type.
3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
我自己正在阅读 C++ primer 的摘录,我认为我已经想出了一种方法来从数学上弄清楚这些值是如何产生的(如果我错了,请随时纠正我:)) .以下面的特定代码为例。
unsigned char c = -4489;
std::cout << +c << std::endl; // will yield 119 as its output
那么119的这个答案是怎么出来的呢?
我们将 4489 除以字符总数,即 2^8 = 256,余数为 137。
4489 % 256 = 137.
现在只需从 256 中减去 137。
256 - 137 = 119.
这就是我们简单导出 mod 值的方式。也请自己尝试其他值。对我来说非常准确!