我正在使用带有Code :: Blocks的MinGW64(带有-m64
标志),并希望知道如何执行64位计算而不必使用以下内容:
int64_t test = int64_t(2123123123) * 17;
如果我使用它,计算溢出并返回1733354723,它应该返回36093093091:
int64_t test = 2123123123 * 17;
我已将我的可执行文件上传到病毒总数,证实我的可执行文件是x64。
编辑:应该提到我在Windows 7 x64上。
答案 0 :(得分:4)
即使在64位编译中,默认的int类型仍然是32位,用于兼容性调整。
我猜的“最短”版本是将ll
后缀添加到数字
int64_t test = 2123123123ll * 17;
另一种方法是将数字存储在自己的int64_t
(或long long
)变量中,然后乘以变量。通常,在程序中很少有很多“魔术数字”硬编码到代码库中。
答案 1 :(得分:4)
曾几何时,大多数计算机都有8位算术逻辑单元和16位地址总线。我们称它们为8位计算机。
我们学到的第一件事就是没有现实世界的算术问题可以用8位表示。这就像试图利用黑猩猩的算术能力推理太空飞行一样。因此,我们学会了编写多字加,乘,减和除序列。因为在大多数现实问题中,问题的数值域大于255。
我们简单地使用了16位计算机(其中应用了相同的问题,65535仅仅不足以模拟事物),然后非常快,内置于芯片的32位算术逻辑。渐渐地,地址总线赶上了(20位,24位,32位,如果设计师感到奢侈的话)。
然后发生了一件有趣的事情。我们大多数人不再需要编写多字算术序列。事实证明,大多数(tm)现实世界的整数问题可以用32位(最多40亿)表示。
然后我们开始以比以往更快的速度生成更多数据,并且我们认为需要处理更多内存。 64位计算机最终成为常态。
但是,大多数现实世界的整数算术问题都可以用32位表示。对于大多数事情来说,40亿是一个很大(足够)的数字。
因此,大概通过统计分析,您的编译器编写者决定在您的平台上,int的最有用大小是32位。对于32位算术(我们从第1天开始需要),任何更小的算法都是低效的,任何更大的算法都会浪费空间/寄存器/内存/ cpu周期。
在c ++(和c)中表达整数文字会产生一个int - 环境的自然算术大小。在今天,这几乎总是32位值。
c ++规范说,乘以两个整数会产生一个int。如果它没有,那么乘以两个整数就需要产生一个长期。但那么两个多头产量会增加多少呢?好久不见?好的,这是可能的。现在,如果我们乘以那些呢?很长很久很长?
这就是那个。
int64_t x = 1 * 2;
将执行以下操作:
long int
。所以简而言之,不。在问题的代码片段中没有拼写出至少一个操作数类型的快捷方式。当然,您可以指定文字。但是不能保证系统上的long long
(LL文字后缀)与int64_t
相同。如果您想要int64_t
,并且希望代码可移植,则必须将其拼写出来。
在后c ++ 11世界中,所有对额外击键和非干扰的担忧都会消失:
绝对是int64:
auto test = int64_t(2123123123) * 17;
肯定是漫长的一段时间:
auto test = 2'123'123'123LL * 17;
绝对是int64,肯定是用一个(可能缩小,但没关系)长期初始化:
auto test = int64_t(36'093'093'091LL);
答案 2 :(得分:3)
由于您最有可能处于LP64环境中,int
只有32位,因此您必须注意表达式中的文字常量。最简单的方法是养成在文字常量上使用正确后缀的习惯,因此你可以将上面的内容写成:
int64_t test = 2123123123LL * 17LL;
答案 3 :(得分:2)
2123123123
是int
(通常是32位)。
添加L
使其成为long
:2123123123L
(通常为32位或64位,即使在64位模式下)。
添加另一个L
使其成为long long
:2123123123LL
(64位或更多,从C ++ 11开始)。
请注意,您只需要将后缀添加到超出int
大小的常量。积分转换将产生正确的结果*。
(2123123123LL * 17) // 17 is automatically converted to long long, the result is long long
*但要注意:即使表达式中的各个常量适合int
,整个操作仍然会像
(1024 * 1024 * 1024 * 10)
在这种情况下,您应确保以足够的宽度执行算术运算(考虑运算符优先级):
(1024LL * 1024 * 1024 * 10)
- 将以64位执行所有3个操作,结果为64位。
答案 4 :(得分:1)
编辑:文字常量(A.K.A.魔术数字)不受欢迎,因此最好的方法是使用符号常量(const int64_t value = 5
)。有关详细信息,请参阅What is a magic number, and why is it bad?。 最好不要阅读本答案的其余部分,除非你真的想因某些奇怪的原因使用魔法数字。
此外,您可以使用intptr_t
中的uintprt_t
和#include <cstdint>
让编译器选择是使用int
还是__int64
。
<德尔> 对于那些偶然发现这个问题的人来说,数字末尾的“LL”可以解决这个问题,但是不建议这样做,因为理查德·霍奇斯告诉我,“long long”可能并不总是64位,并且可以增加未来的规模,虽然不太可能。有关更多信息,请参阅Richard Hodge的回答及其评论。 德尔>
<德尔> 可靠的方法是将`使用QW = int_64t;`放在顶部并使用`QW(5)`而不是'5LL`。 德尔>
<德尔> 我个人认为应该有一个选项来定义64位的所有文字,而不必向它们添加任何后缀或函数,并在必要时使用`int32_t(5)`,因为某些程序不受此更改的影响。示例:仅使用数字进行正常计算,而不是依靠整数溢出来完成它的工作。问题是从64位变为32位,而不是从32位变为64位,因为前4个字节被切断。 德尔>