为什么在C++11中,unsigned short * unsigned short
会转换成int
?
由于这行代码所示,int
太小了,无法处理最大值。
cout << USHRT_MAX * USHRT_MAX << endl;
MinGW 4.9.2 上的溢出问题
-131071
因为 (来源):
USHRT_MAX = 65535 (2^16-1) 或更高*
INT_MAX = 32767 (2^15-1) 或更高*
而且 (2^16-1)*(2^16-1) = ~2^32。
这个解决方案会有什么问题吗?
unsigned u = static_cast<unsigned>(t*t);
这个程序
unsigned short t;
cout<<typeid(t).name()<<endl;
cout<<typeid(t*t).name()<<endl;
产生输出
t
i
on
gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)
gcc version 4.8.2 (GCC)
MinGW 4.9.2
与两者皆有
g++ p.cpp
g++ -std=c++11 p.cpp
这证明在这些编译器上,
t*t
被转换为 int
。
有用的资源:
https://bytes.com/topic/c-sharp/answers/223883-multiplication-types-smaller-than-int-yields-int
http://www.cplusplus.com/reference/climits
http://en.cppreference.com/w/cpp/language/types
编辑:我已在以下图片中演示了问题。
int
是16位,则您得到的结果不是一个int
。请注意,您链接到的表格中的值的免责声明:“实际值取决于特定系统和库实现,但应反映目标平台上这些类型的限制。” - Some programmer dudeUSHRT_MAX
是unsigned short
类型吗?在我的环境下(Lubuntu 下的 GCC 4.8 64 位),USHRT_MAX
实际上是int
类型(定义为(32767 * 2 + 1)
)。难怪USHRT_MAX*USHRT_MAX
会溢出。 - Paolo MUSHRT_MAX
是0xFFFF
,而0xFFFF * 0xFFFF = 0xFFFE0001
(没有溢出)。这相当于4294836225
或-131071
,所以只是最终转换为int
时才会出现问题。 - Barmak ShemiraniINT_MAX
是0x7FFFFFFF
,所以这实际上是溢出。 - M.M