整数溢出错误在Delphi 11.2中,但在Delphi 10.4.2中没有



我正在尝试将Delphi 6中的旧pascal程序转换为Delphi 11.2 Alexandria。

我有下面的函数,它用A的倍数填满模表,模是anArray [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 11.2我得到一个整数溢出错误在ModuloPointer^:= ((NPointer^ * I) + Remainder);当抛出错误时,I的值仅为2。

当我在Delphi 10.4.2上运行相同的过程时,没有整数溢出错误,一切都很好。

我真的想不出这里出了什么问题,我试过将ModuloPointer,NPointer转换为Uint64,Modulo转换为Word,但没有成功(可能没有意义)。

我错过了一些相当简单的东西还是在Delphi 11.2 IDE中有一些变化?不管怎样,我们怎么解决这个问题,出了什么问题?

与指针杂耍类似的是:

type
TCode128= packed record
case Byte of  // The same length for all variants, equal to UNIONs in C
1: ( b: Array[0.. 15] of Byte );  // Accessing as 16 bytes
2: ( c: Array[0.. 3] of Cardinal );  // As 4 DWORDs
3: ( w: Array[0.. 7] of Word );  // As 8 WORDs
end;
var
Modulo: Array[0.. 255] of Array[0.. 4] of Cardinal;  // DWORDs where we need them
procedure SetModulo( A: TCode128 );
var
I, J, Remainder: Byte;
begin
for I:= 0 to 255 do begin  // For each "modulo"
Remainder:= 0;
for J:= 0 to 3 do begin  // Each first 4 remainders
// Access and store as DWORDs right away
// Allowing a higher product/sum than CARDINAL could hold, but only store 32 bit
Modulo[I][J]:= (Int64(A.c[J])* I+ Remainder) and $FFFFFFFF;
Remainder:= (A.w[J* 2]* I+ Remainder) div $10000;  // Access as WORDs
Remainder:= (A.w[J* 2+ 1]* I+ Remainder) div $10000;
end;
Modulo[I][4]:= Remainder;  // Last 5th remainder
end;
end;
如您所见,这在逻辑上更容易理解,需要更少的变量,并且与平台无关。TCode128定义有3个变量,但它们都指向相同的内存——这样你就可以用多种方式定义内存,以便以后访问它,对大脑和数据类型更友好。

Cardinal乘以255并再次添加最大255可能会溢出,因为它只适用于16843008($1010100)的值。这就是为什么我只选择那个product/sum的(最小的)32位

相关内容

最新更新