32位整数 * 32位整数 = 64位整数?

6
换句话说,这个是否按照预期工作?
int32 i = INT_MAX-1;
int64 j = i * i;

或者我需要先将 i 转换为 64 位吗?

2
这取决于你的期望 - 但是Will Dean关于发生的事情是正确的,而且很可能不是你所期望的。 - Jonathan Leffler
请查看:https://dev59.com/mXVC5IYBdhLWcg3wlyMo#245986 - Martin York
5个回答

17
您需要将至少一个操作数转换为乘积。 在执行乘法时,系统不知道您打算分配给 int64。
(除非 int64 实际上是您特定系统的本机 int 类型,这似乎不太可能)

5
常用技巧是先将1L乘上,而不是进行强制类型转换:int64 j = 1L * i * i;如果你的long类型长度为64位,则该方法适用。 - stepancheg
3
如果你的 long 只有32位,你可以在大多数现代编译器上使用1LL。 - Head Geek
1
或者您可以使用stdint.h中的INT64_C(1)使其具有合理的可移植性(您可能需要从MinGW或http://www.azillionmonkeys.com/qed/pstdint.h获取MS编译器的stdint.h)。 - Michael Burr
1
什么是 int32 和 int64?它们是否应该像<stdint.h> 中的 int32_t 和 int64_t 一样? - Hudson

7

这取决于int32和int64是什么。

简而言之,在进行任何算术运算之前,所有整数都会提升至至少'int'大小(可能为64位),如果二元运算符的较大操作数的等级高于int,则会提升为该操作数的大小。

表达式的结果如何使用(是否存储到更宽的类型中)对表达式组成部分的提升没有影响。


3
基本答案是否定的,它不会做你想要的事情。
但它确实会做预期的事情。
关于数学运算需要注意两点:
  • 两个操作数将是相同的类型。
  • 结果类型将与输入类型相同。
如果编译器注意到操作数之间存在不匹配,它将转换其中一个操作数以使两者匹配(请参阅Which variables should I typecast when doing math operations in C/C++?)。注意:这是在不考虑结果会发生什么的情况下完成的。

0

给出两个数字a,b,每个数字使用len_a和len_b位。

你的输出数据类型至少需要:len_a和len_b位。

在你上面的代码中,你有两个31位的数字(因为INT_MAX - 1 = 0x7FFFFFFE使用31位),你将需要将它们中的一个转换为int64_t,因为它将进行32位乘法并溢出,然后再转换为int64_t。


固定点乘法所需的位数:
len_output = howManyBits( a * b )
           = len_a + len_b

一个快速的示例来展示上述规则的实际应用:
a     = 7
len_a = 3

b     = 7
len_b = 3

c = a * b
  = 49 ( decimal )
  = 0x31 ( hex )

len_c = howManyBits( 0x31 ) 
      = 6

你可以编写一个函数来计算位数。或者,如果您只想进行快速的健全性检查以确认这一点,请使用Windows Calc之类的工具将数字转换为二进制形式并计算使用的位数。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接