我正在尝试将一个旧的pascal程序从 Delphi 转换成Delphi11.2Alexandria。
我有下面的函数,它用A的倍数填充模表,模是Array [0..255, 0..19] of Byte
。
procedure TForm.SetModulo(A: TCode128);
var
I, J, Remainder : Byte;
NPointerStart: PCardinal;
NPointer: PCardinal;
ModuloPointer: PCardinal;
WordPointer: PWord;
begin
NPointerStart:= Addr(A);
for I:= 0 to 255 do begin
NPointer:= Pointer(NPointerStart);
Remainder:= 0;
ModuloPointer:= Addr(Modulo[I][0]);
for J:= 0 to 3 do begin
ModuloPointer^:= ((NPointer^ * I) + Remainder); //<- Int Overflow error
WordPointer:= Pointer(NPointer);
Remainder:= ((WordPointer^ * I) + Remainder) div $10000;
Inc(WordPointer);
Remainder:= ((WordPointer^ * I) + Remainder) div $10000;
Inc(NPointer);
Inc(ModuloPointer);
end;
ModuloPointer^:= Remainder;
end;
end;
程序参数TCode128为Array[0..15] of Byte
,发送字节地址为($12, $C4.......)
。
在 Delphi 中,我在ModuloPointer^:= ((NPointer^ * I) + Remainder);
处得到一个整数溢出错误。当它抛出错误时,I的值正好是2。
当我在 Delphi 上运行相同的过程时,没有整数溢出错误,一切都很好。
我真的想不出这里出了什么问题,我试着将ModuloPointer
、NPointer
类型转换为Uint64
,将Modulo
类型转换为Word
,但没有成功(可能没有意义)。
我是否遗漏了一些非常简单的东西,或者 Delphi 11.2 IDE中有一些变化?无论如何,我们如何解决这个问题,哪里出了问题?
1条答案
按热度按时间lh80um4z1#
指针杂耍的等价形式是:
正如你所看到的,这在逻辑上更容易理解,需要更少的变量,并且是平台无关的。
TCode128
定义有3个变量,但是它们都指向同一个内存-这样你就可以用多种方式定义内存,以便以后访问它,这对大脑和数据类型都更友好。将
Cardinal
乘以255
,然后在最大255
处相加,很容易产生溢出,因为它只适用于16843008
($1010100
)以内的值,这就是为什么我只选择乘积/和的(最小)32位。