这里我说一下,把ax :=(a*m) shr 21;改为ax :=int64(a*m) shr 21结果就正确了,但是谁能解释一下为什么不加int64会出错?
解决方案 »
- 100分求delphi技术方案宝典光盘
- delphi2005 Activex 嵌入网页的问题
- 如果压缩一文件,然后做成res资源?
- 怎样判断pchar字符串为空值?
- 时机已经成熟,再加上一个有意义点的求婚就可大功告成,请大富翁们帮忙想个DEMO!!(60大洋)
- 菜鸟问题:如何通过自己设置的特殊字符来拆分字符串
- 怎样能使ADOTable1连接的表按指定的列排序?谢谢
- 如何让WEBBrowser这个控件在界面上隐藏起来?
- 如何通过编程来检测本机上网与否?
- 请问那里有关于b/s的论文(最好是delphi方面的)?
- DELPHI XE 哪个版本好用,用过的来说下感受,只做普通VCL程序
- delphi怎样彻底删除一个件,而不是去回收站?
而delphi的右移则是无符号右移,对应汇编指令是shr
看下俩者反汇编就知道了。
a,m,aa:Integer;
begin
a :=29959314 ;
m :=-3;
asm
push eax
push ebx
mov eax, a
mov ebx, m
imul eax, ebx
sar eax,21
mov aa, eax
pop ebx
pop eax
end;
之所以产生-43的结果,是编译器在编译时求值(29959314*-3) shr 21;做了不正确的处理(可能是Delphi和CB共享编译器后端造成的BUG,不过后来已经修正了)。
而int64默认有8个字节,有效值域达十几位数,不会溢出,自然就对了。
在delphi xe5仍然是这样,lazarus是正确的。参考<<delphi陷阱大全>>
(a*m),Delphi当什么处理?(29959314*-3),Delphi又当什么处理?如果处理方式一样,结果应该都一样。为什么会出现两个结果,如果说(a*m)是Integer,哪个地方显式说明了它是Integer,为什么不是int64,或者为什么不是WORD?(29959314*-3)为什么不是Integer,看起来倒更像int64,因为这个,调试了半天。
Point Axis::translate(int moveX, int moveY)
{
long dp = DECIMAL_POINT;
Point point;
int dx = (moveX == 0) ? 0 : (modulePitch * moveX) >> dp;
int dy = (moveY == 0) ? 0 : (modulePitch * moveY) >> dp;
point.translate((dx * cos - dy * sin) >> dp, (dx * sin + dy * cos) >> dp);
point.translate(origin.x, origin.y); return point;
}该函数被以下函数引用
//精确版本号
int FinderPattern::calcExactVersion(Point * centers, int * angle, int * moduleSize)
{
BYTE * VersionInfo = new BYTE[18];
Point * points = new Point[18];
Point target;
int m=angle[0],n=angle[1];
//右上 --- 版本信息1
Axis axis = Axis(angle, moduleSize[UR], DECIMAL_POINT); //UR
m=angle[0];n=angle[1];
axis.setOrigin(centers[UR]);
for (int y = 0; y < 6; y++) {
for (int x = 0; x < 3; x++) {
target = axis.translate(x - 7, y - 3);//此处调用
VersionInfo[x + y * 3] = bitmap[target.x][target.y];//其返回结果直接被数组调用
Delphi代码如下:
function TAxis.Translate(moveX, moveY: Integer): TPoint;
var
dp,dx,dy:Integer;
begin
dp := DECIMAL_POINT;
if moveX=0 then
dx :=0
else
dx := int64(FModulePitch * moveX) shr dp;
if moveY=0 then
dy :=0
else
dy := int64(FModulePitch * moveY) shr dp; //为何要加in64强行转换?????,不加就出错!!!!
Result :=Point(0,0);
Result.X :=Result.X+ int64(dx * FCos - dy * FSin) shr dp;//同样加int64,否则出错
Result.Y :=Result.Y+ int64(dx * FSin + dy * FCos) shr dp;//同样加int64,否则出错
Result.X :=Result.X+ FOrigin.x;
Result.Y :=Result.Y+ FOrigin.y;
end;该函数算出target结果后直接被一个数组使用,未做任何处理,C++最后的结果·是在数组内,但是Delphi算出的数字N大(如果不按-43处理),远超出数组范围,程序直接崩溃,代码太繁杂了,算法也看不懂,只能照抄,但是C++似乎看不出对于-43的结果采用将错就错的处理方式。