Delphi 如何从shl获得大于2^32的结果?

Delphi 如何从shl获得大于2^32的结果?,delphi,64-bit,bit-shift,Delphi,64 Bit,Bit Shift,声明 const n = 2 shl 33 将常量n设置为值4,无需任何编译器投诉 还有 Caption := IntToStr(2 shl 33); …返回4而不是8589934592。 看起来编译器的计算如下: 2先令33=2先令(33和1美元)=4 但没有任何警告或溢出 如果我们宣布: const n: int64 = 2 shl 33; 常数中的数字仍然是4,而不是8589934592 任何合理的解决方法?根据Delphi编译器和Windows 7的计算器在程序员模式下的说

声明

const
  n = 2 shl 33
将常量
n
设置为值4,无需任何编译器投诉

还有

Caption := IntToStr(2 shl 33);
…返回4而不是8589934592。 看起来编译器的计算如下:

2先令33=2先令(33和1美元)=4

但没有任何警告或溢出

如果我们宣布:

const
  n: int64 = 2 shl 33;
常数中的数字仍然是4,而不是8589934592


任何合理的解决方法?

根据Delphi编译器和Windows 7的计算器在程序员模式下的说法,您正在寻找错误的结果。(你想要的答案实际上是
2shl32
,顺便说一句。)

您需要将
shl
的两侧强制转换为
Int64

const
  n = Int64(2) shl Int64(33);
这就产生了

N = 17179869184;

当前版本(适用于XE2,但也适用于Delphi的早期版本)在
基本整数类型中指出了这一点。但是,该页提到只需将其中一个操作数强制转换为
Int64
;我的测试表明,它要求在上面的
const
声明中对两个操作数进行类型转换-仅对一个操作数进行类型转换(不管是哪一个操作数)也会导致“n=4;”

为什么期望32位整数有这么大的值?它只能容纳2^32个不同的值。@CodeInChaos:我希望至少有编译器工作@GJ:没有编译器错误保证。没有溢出。使用
Int64
时对强制转换的需求自首次引入以来就已经有了文档记录(在有Delphi文档的时候)。我会看看是否能找到一个引用并更新我的答案。好吧,我的错误是,正确的结果是17179869184,但我希望至少编译器正在运行。恐怕你得和Embarcadero谈谈编译器警告;我本人对此没有影响。:)但由于它是按文档记录的方式工作的,我不认为在哪里需要警告-它在上面的链接中有文档记录,并且自引入
Int64
以来就有文档记录。文档中的确切引用:“仅当对一个或多个Int64操作数执行操作时,才会返回Int64类型的值。”。由于两个操作数(赋值右侧的值)都不是Int64,因此不会返回Int64。无需警告-按设计和文档说明工作。如果赋值的结果是Int64,则不需要将常量的类型定义为Int64。在上面的示例中,您可以简单地使用
const n=Int64(2)shl Int64(33)。这也将允许
n
作为真常量而不是类型化常量。否,@GJ。不一样。前者是单个标记,编译器可以立即看到它大于32位类型,因此它使用Int64作为类型。后者是三个标记,两个数字标记都被指定为整数类型,因为它们足够小,可以容纳。语言定义说,应用于两个整数操作数的
shl
本身就是一个整数,而不是Int64。当其他人可能希望使用相同的代码得到(向后兼容的)较小的结果时,编译器如何知道您想要的是更大的结果?实际上,@GJ.,在旧代码中等于1,在Delphi使用64位整数类型之前编写。它被很好地定义为1,因为右操作数总是被截断为5位。为了保持向后兼容性,这种行为需要保持15年前的状态,否则人们的程序会突然中断。