Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有符号字符的乘法问题_C++_Visual Studio - Fatal编程技术网

C++ 有符号字符的乘法问题

C++ 有符号字符的乘法问题,c++,visual-studio,C++,Visual Studio,在讨论答案时,我发现下面的代码在visual studio中打印-1和1。为什么?在我看来,它应该打印两个1s,而不是乘法过程中的溢出 signed char c1 = numeric_limits<signed char>::min(); signed char c2 = -1; cout << c1 * c2 / c1 << endl; signed char result = c1 * c2; cout << result / c1 <

在讨论答案时,我发现下面的代码在visual studio中打印
-1
1
。为什么?在我看来,它应该打印两个
1
s,而不是乘法过程中的溢出

signed char c1 = numeric_limits<signed char>::min();
signed char c2 = -1;
cout << c1 * c2 / c1 << endl;
signed char result = c1 * c2;
cout << result / c1 << endl;
signed char c1=numeric_limits::min();
有符号字符c2=-1;

cout整数溢出被认为是UB。这意味着编译器将考虑<代码>(C1*C2/C1)完全等同于<代码> C2< /代码>。
您可以查看其他信息。

整数溢出被视为UB。这意味着编译器将考虑<代码>(C1*C2/C1)完全等同于<代码> C2< /代码>。
您可以查看其他信息。

c1
的值可能类似于
-128
。在乘法中,整数提升将导致
c1
c2
在执行运算之前转换为类型
int

c1*c2
然后将是一个值为
128
int
,因此
c1*c2/c1
将是一个值为
-1
int

-1
对于第一个输出,我认为是正确的


对于第二个版本,通常情况下,
c1*c2
的结果赋值将不适合
有符号字符
,并将转换为实现定义的结果,例如,可能
-128
而不是
128

c1
可能具有类似
-128
的值。在乘法中,整数提升将导致
c1
c2
在执行运算之前转换为类型
int

c1*c2
然后将是一个值为
128
int
,因此
c1*c2/c1
将是一个值为
-1
int

-1
对于第一个输出,我认为是正确的


对于第二个版本,通常
c1*c2
结果的赋值将不适合
有符号字符
,并将转换为实现定义的结果,可能
-128
而不是
128

c1*c2
int
乘法(标准中为5/9)。我们知道在MSVC上CHAR_位是8,并且它对有符号类型使用2的补码表示,所以我们知道值:-128*-1是128

128/-128是-1,所以这是排序的第一个结果


-CHAR\u MIN
分配给
有符号字符
有实现定义的结果(4.7/3),但我们知道在MSVC中结果是-128。然后-128/-1是1,这是第二个排序结果。

c1*c2
是一个
int
乘法(标准中为5/9)。我们知道在MSVC上CHAR_位是8,并且它对有符号类型使用2的补码表示,所以我们知道值:-128*-1是128

128/-128是-1,所以这是排序的第一个结果


-CHAR\u MIN
分配给
有符号字符
有实现定义的结果(4.7/3),但我们知道在MSVC中结果是-128。然后-128/-1是1,所以这是第二个排序结果。

第一种情况,使向上缩放为int显式:

cout << ((int)c1 * c2 / c1 << endl;

cout第一种情况,使向上缩放为int显式:

cout << ((int)c1 * c2 / c1 << endl;

cout
c1*c2
可能不涉及任何有符号整数溢出,除非平台具有大小相同的
char
int
@Charles:它没有(它是Visual Studio).
c1*c2
可能不涉及任何有符号整数溢出,除非平台具有相同大小的
char
int
。@Charles:它没有(它是Visual Studio)。但是为什么
c1*c2
将成为
int
?这是标准吗?@Mihran因为整数promotion@MihranHovespyan:整数提升适用于
*
的两个操作数,因此在执行乘法之前,两个
有符号字符
都将提升为
int
。尽管看起来很奇怪,但您可以用一个简单的测试程序验证这一点:
void foo(int){std::cout但是为什么
c1*c2
会是
int
?这是标准吗?@Mihran因为整数promotion@MihranHovespyan:整数提升适用于
*
的两个操作数,因此在执行乘法之前,这两个
有符号字符将被提升为
int
。尽管看起来很奇怪,您可以n用一个简单的测试程序来验证这一点:
void foo(int){std::cout升级到
int
是多余的,实现还是会这样做的
算术运算没有溢出,存在从一个整数类型到另一个整数类型的显式转换。这将是实现定义的,而不是欠定义的行为。升级到
int
是多余的,实现无论如何都会这样做。在这种情况下,在
(带符号字符)((int)c1*c2)中
算术运算没有溢出,而是从一个整数类型到另一个整数类型的显式转换。这是实现定义的,而不是欠定义的行为。