首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

奇异的Delphi运算结果,什么原因造成

2014-01-17 
怪异的Delphi运算结果,什么原因造成?代码如下vardx,m,ax,a:Integerbegina :29959314 m :-3ax :(a*m)

怪异的Delphi运算结果,什么原因造成?
代码如下
var
  dx,m,ax,a:Integer;
begin
  a :=29959314 ;
  m :=-3;
  ax :=(a*m) shr 21;
  dx :=(29959314*-3) shr 21;
end;
知道 ax的结果吗?是2005,知道dx的结果吗?是-43,我勒个去的,Delphi7怎么会这样出两个结果,正确结果是-43,因为C++执行结果就是-43,有谁知道如何解决?因为29959314和-3两个数值会变,我只是出现错误调试时居然发现这里会这样奇异的Delphi运算结果,什么原因造成
[解决办法]
因为c++的右移是有符号右移,对应汇编指令是sar
而delphi的右移则是无符号右移,对应汇编指令是shr
看下俩者反汇编就知道了。
[解决办法]
2005是对的,Delphi的shr只做逻辑右移,与操作数有符号还是无符号无关,一律做无符号数处理,这在Turbo pascal时代就是一个见于文档的正式特性,与C和C++的>>处理方法不同。
之所以产生-43的结果,是编译器在编译时求值(29959314*-3) shr 21;做了不正确的处理(可能是Delphi和CB共享编译器后端造成的BUG,不过后来已经修正了)。

[解决办法]
其实原因很简单,因为integer默认只有两个字节,有效值域才正负60000多,你给他一个这么大的数,自然就溢出了,溢出以后能不能保证数字的样子就难说了。
而int64默认有8个字节,有效值域达十几位数,不会溢出,自然就对了。
[解决办法]
n b ,delphi 默认将整数常数向int32bit靠近,如果要将大常数赋值给变量,加强制转换成int64。
在delphi xe5仍然是这样,lazarus是正确的。

参考<<delphi陷阱大全>>

热点排行