当前位置: 首页 > 知识库问答 >
问题:

为什么要将无符号short(multiply)无符号short转换为有符号int?[副本]

耿运浩
2023-03-14

为什么在C 11中无符号短*无符号短转换为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

在…上

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

C语言中的有符号到无符号转换-总是安全的吗?

签名了

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

编辑:我已经在下图中演示了该问题。

共有3个答案

易品
2023-03-14
匿名用户

正如Paolo M在注释中指出的,USHRT_MAX的类型为int(这由5.2.4.21/1指定:所有此类宏的类型至少与int一样大)。

因此,USHRT\u MAX*USHRT\u MAX已经是一个intxint,不会发生升级。

这会在系统上调用有符号整数溢出,导致未定义的行为。

关于提议的解决方案:

unsigned u = static_cast<unsigned>(t*t);

这没有帮助,因为t*t本身会由于有符号整数溢出而导致未定义的行为。正如其他答案所解释的那样,由于历史原因,t在乘法发生之前被提升为int

相反,您可以使用:

auto u = static_cast<unsigned int>(t) * t;

在整数提升后,它是无符号整数乘以整数;然后,根据其余的常用算术转换,将int提升为无符号int,并发生定义良好的模乘。

樊飞飙
2023-03-14

这是常用的算术转换。

通常被称为参数提升,尽管标准使用该术语的方式更加有限(合理的描述性术语和标准之间的永恒冲突)。

“许多期望操作数为算术或枚举类型的二进制运算符会导致转换,并以类似的方式生成结果类型。目的是生成一个公共类型,它也是结果的类型。这种模式称为常用的算术转换[…]

这一段继续描述细节,相当于在更一般的类型的阶梯上进行转换,直到可以表示所有参数为止。此阶梯上的最低一级是二进制操作的两个操作数的整数提升,因此至少可以执行此操作(但转换可以从较高的一级开始)。整体推广从以下方面开始:

“如果整数转换秩(4.13)小于int的秩,则除boolchar16\u tchar32\u twchar\u t以外的整数类型的PR值可以转换为int类型的PR值,前提是int可以表示源类型的所有值;否则,可以将源prvalue转换为类型为无符号int的prvalue

关键是,这是关于类型,而不是算术表达式。在本例中,乘法运算符的参数将转换为int。然后将乘法作为int乘法执行,产生int结果。

澹台奇略
2023-03-14

您可能想阅读有关隐式转换的内容,尤其是关于数字促销的部分

小整数类型(如char)的pr值可转换为大整数类型(如int)的pr值。特别是,算术运算符不接受小于int的类型作为参数

上面所说的是,如果在包含算术运算符(当然包括乘法)的表达式中使用小于int的值(如无符号short),则值将提升为int。

 类似资料:
  • 问题内容: 我必须将字节转换为有符号/无符号int或short。 下面的方法正确吗?哪个是签名的,哪个是未签名的? 字节顺序:LITTLE_ENDIAN VS。 和 VS。 我 只 对这种转换形式感兴趣。谢谢! 问题答案: 每对中的第一个方法()是带符号的,第二个()是无符号的。 但是,Java 始终是带符号的,因此,如果设置的最高位,则即使将其视为“无符号”版本,其结果也将为负。 假设值是-1或

  • 问题内容: 在C语言中,我可以使用数字做一些技巧: 在Swift中有没有办法做到这一点?请注意,相同的方法无效: 有没有一种方法可以让C的行为在Swift中减法? 谢谢! 问题答案: 所有有符号和无符号整数类型都有一个构造函数,该构造函数从具有相同内存表示形式的有符号(反之亦然)创建无符号数字:

  • 我正在解决一个问题,其中的任务是在用户提到的给定行输出pascal三角形的结果。 https://leetcode.com/problems/pascals-triangle-ii/ 我写了我的解决方案,其中有存储巨大阶乘结果的问题。 通过这些问题, 整数类型可以在C中存储哪些范围的值 长到无符号的字节数是多少? 并通过其他一些来源,我进行了以下更改,这给了我所需的结果。 由于“C”是int类型,

  • 问题内容: 在Java中,是否有一种简单而优雅的方法将无符号字节值转换为有符号字节值?例如,如果我所拥有的只是int值240(二进制(24位+ 11110000)= 32bits),如何获得该int的带符号值? 问题答案: 除了,Java没有其他无符号值。考虑以下代码段: 结果将为-1,因为最低的8位已复制到byte变量中。

  • 问题内容: 假设我有这个号码。我如何将其称为无符号变量?像C一样 问题答案: 假设 : 您会想到2的补码表示法;和, 通过您 的意思是 32位无符号整数, 那么您只需将其添加为负值即可。 例如,将此应用于-1: 假设1表示您希望将-1视为一个1位的实字符串,而假设2表示您希望其中的32个。 但是,除了你,没人可以说你隐藏的假设是什么。例如,如果考虑到1的补码表示形式,则需要应用前缀运算符。Pyth

  • 我在尝试将未签名的 char 数组转换为 jstring 时遇到问题。 上下文是我正在使用来自Java的共享c库。所以我正在实现一个JNI c文件。我在库中使用的函数会恢复 我在 JNI C 文件中实现的函数返回一个 jstring。 所以我需要把无符号的char数组转换成jstring。 但是,尽管数组应该只包含20个字节,但我在Java中随机得到22或23个字节......(虽然 20 个字节