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

GJ.*_*GJ. 6 delphi 64-bit bit-shift

宣言...

const
  n = 2 shl 33
Run Code Online (Sandbox Code Playgroud)

n在没有编译器投诉的情况下将常数设置为值4!

也...

Caption := IntToStr(2 shl 33);
Run Code Online (Sandbox Code Playgroud)

...返回4而不是8589934592.看起来编译器计算如下:

2 shl 33 = 2 shl(33和$ 1F)= 4

但没有任何警告或溢出.

如果我们声明:

const
  n: int64 = 2 shl 33;
Run Code Online (Sandbox Code Playgroud)

常数中的数字仍然是4而不是8589934592.

任何合理的工作?

Ken*_*ite 13

根据Delphi编译器和Windows 7程序员模式的计算器,你正在寻找错误的结果.(你想要的答案实际上就是2 shl 32BTW.)

你需要将两侧投射shlInt64:

const
  n = Int64(2) shl Int64(33);
Run Code Online (Sandbox Code Playgroud)

这产生了

N = 17179869184;
Run Code Online (Sandbox Code Playgroud)

当前的文档(对于XE2,但也适用于早期版本的Delphi)注意到了这一点Fundamental Integer Types.但是,该页面提到只需要将其中一个操作数转换为Int64; 我的测试表明它要求两个操作数在const上面的声明中进行类型转换- 仅对一个(无论哪一个)进行类型转换也导致"n = 4;".

  • 不,@ GJ.这是不一样的.前者是单个令牌,编译器可以立即看到它比32位类型更大,因此它使用Int64作为类型.后者是三个令牌,两个数字令牌都被赋予Integer类型,因为它们足够小以适应.语言定义说,应用于两个整数操作数的`shl`本身就是一个Integer,而不是一个Int64.当其他人可能想要使用相同代码的(向后兼容的)更小的结果时,编译器如何知道你想要更大的结果? (4认同)
  • 我担心你不得不和Embarcadero谈论编译器警告; 我对自己没有影响力.:)但是由于它的工作情况已经记录完毕,我没有看到哪里需要警告 - 它已在上面的链接中记录,并且自从引入了Int64`以来已被记录.来自文档的确切引用:"仅当在一个或多个Int64操作数上执行时,操作才返回Int64类型的值." 由于两个操作数(赋值右侧的值)都不是Int64,因此未返回Int64.无需警告 - 按设计和记录工作. (3认同)
  • 如果赋值的结果是Int64,则不需要将常量的类型定义为Int64.在上面的例子中,你可以简单地使用`const n = Int64(2)shl Int64(33);`.这也将允许`n`表现为真正的常量而不是类型常量. (2认同)
  • 实际上,@ GJ.,在旧代码的情况下它等于1,在Delphi之前写入64位整数类型.它被定义为1,因为右操作数总是被截断为5位.为了保持向后兼容性,这种行为今天需要保持与15年前相同,否则人们的程序会突然中断. (2认同)