mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 05:59:28 +02:00
363 lines
11 KiB
ObjectPascal
363 lines
11 KiB
ObjectPascal
program mymodtest;
|
|
|
|
{$MODE DELPHI}
|
|
{$ASSERTIONS ON}
|
|
|
|
// Pascal implementation of signed modulus by power of 2 constant algorithm
|
|
function my_modulus(x, m : integer) : integer;
|
|
var
|
|
temp, mask1, mask2 : integer;
|
|
begin
|
|
m := abs(m-1);
|
|
|
|
temp := x and m;
|
|
|
|
if (x < 0) then begin // = sign bit
|
|
mask2 := -1;
|
|
end else begin
|
|
mask2 := 0;
|
|
end;
|
|
|
|
if (temp <> 0) then begin // note: temp >= 0
|
|
mask1 := -1;
|
|
end else begin
|
|
mask1 := 0;
|
|
end;
|
|
|
|
my_modulus := temp or ((not m) and mask1 and mask2);
|
|
end;
|
|
|
|
function i32_modulus(x, m : integer) : integer;
|
|
var
|
|
temp : integer;
|
|
begin
|
|
temp := x div m;
|
|
i32_modulus := x - (temp*m);
|
|
end;
|
|
|
|
function u32_modulus(x, m : dword) : dword;
|
|
var
|
|
temp : dword;
|
|
begin
|
|
temp := x div m;
|
|
u32_modulus := x - (temp*m);
|
|
end;
|
|
|
|
var
|
|
i : integer;
|
|
j, k : longint;
|
|
res, res2 : longint;
|
|
|
|
y, z : dword;
|
|
|
|
begin
|
|
randseed := 1; // just take any, but repeatable
|
|
write('positive int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 19;
|
|
assert((j div 19) = (j div k), 'Wrong int32 division by 19 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('Negative int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -19;
|
|
assert((j div -19) = (j div k), 'Wrong int32 division by -19 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 3;
|
|
assert((j div 3) = (j div k), 'Wrong int32 division by 3 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('Negative int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -3;
|
|
assert((j div -3) = (j div k), 'Wrong int32 division by -3 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 7;
|
|
assert((j div 7) = (j div k), 'Wrong int32 division by 7 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('Negative int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -7;
|
|
assert((j div -7) = (j div k), 'Wrong int32 division by -7 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 5;
|
|
assert((j div 5) = (j div k), 'Wrong int32 division by 5 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('Negative int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -5;
|
|
assert((j div -5) = (j div k), 'Wrong int32 division by -5 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 512;
|
|
assert((j div 512) = (j div k), 'Wrong int32 division by 512 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('Negative int32 division test...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -512;
|
|
assert((j div -512) = (j div k), 'Wrong int32 division by -512 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
write('positive int32 modulus test (19)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 19;
|
|
assert((j mod 19) = (i32_modulus(j,k)), 'Wrong int32 modulus by 19 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
|
|
write('Negative int32 modulus test (-19)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -19;
|
|
res := j mod -19;
|
|
res2 := i32_modulus(j, k);
|
|
assert((res = res2), 'Int32 mod by -19 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive int32 modulus test (3)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 3;
|
|
assert((j mod 3) = (i32_modulus(j,k)), 'Wrong int32 modulus by 3 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
|
|
write('Negative int32 modulus test (-3)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -3;
|
|
res := j mod -3;
|
|
res2 := i32_modulus(j, k);
|
|
assert((res = res2), 'Int32 mod by -3 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive int32 modulus test (5)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 5;
|
|
assert((j mod 5) = (i32_modulus(j,k)), 'Wrong int32 modulus by 5 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
|
|
write('Negative int32 modulus test (-5)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -5;
|
|
res := j mod -5;
|
|
res2 := i32_modulus(j, k);
|
|
assert((res = res2), 'Int32 mod by -5 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive int32 modulus test (7)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 7;
|
|
assert((j mod 7) = (i32_modulus(j,k)), 'Wrong int32 modulus by 7 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
|
|
write('Negative int32 modulus test (-7)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -7;
|
|
res := j mod -7;
|
|
res2 := i32_modulus(j, k);
|
|
assert((res = res2), 'Int32 mod by -7 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive int32 modulus test (512)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := 512;
|
|
assert((j mod 512) = (i32_modulus(j,k)), 'Wrong int32 modulus by 512 for j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
|
|
write('Negative int32 modulus test (-512)...');
|
|
for i := -10000 to 10000 do begin
|
|
j := random(high(integer));
|
|
if (random(2) = 1) then j := -j;
|
|
k := -512;
|
|
res := j mod -512;
|
|
res2 := i32_modulus(j, k);
|
|
assert((res = res2), 'Int32 mod by -512 j=' + hexstr(j,sizeof(j)*2) + ' k=' + hexstr(k, sizeof(k)*2) + ' is ' + hexstr(res, 8) + ' ' + hexstr(res2, 8));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 division test (19)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 19;
|
|
assert((y div 19) = (y div z), 'Wrong uint32 division by 19 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 modulus test (19)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 19;
|
|
assert((y mod 19) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 19 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 division test (3)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 3;
|
|
assert((y div 3) = (y div z), 'Wrong uint32 division by 3 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 modulus test (3)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 3;
|
|
assert((y mod 3) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 3 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 division test (5)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 5;
|
|
assert((y div 5) = (y div z), 'Wrong uint32 division by 5 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 modulus test (5)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 5;
|
|
assert((y mod 5) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 5 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 division test (7)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 7;
|
|
assert((y div 7) = (y div z), 'Wrong uint32 division by 7 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 modulus test (7)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 7;
|
|
assert((y mod 7) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 7 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
|
|
write('positive uint32 division test (512)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 512;
|
|
assert((y div 512) = (y div z), 'Wrong uint32 division by 512 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 modulus test (512)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := 512;
|
|
assert((y mod 512) = (u32_modulus(y,z)), 'Wrong uint32 modulus by 512 for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
{ extra test for div by constant optimization }
|
|
write('positive uint32 division test ($deadbeef)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := $deadbeef;
|
|
assert((y div $deadbeef) = (y div z), 'Wrong uint32 division by $deadbeaf for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
|
|
write('positive uint32 division test ($b16beef)...');
|
|
for i := -10000 to 10000 do begin
|
|
y := random(high(integer));
|
|
if (random(2) = 1) then y := 2 * y;
|
|
z := $b16beef;
|
|
assert((y div $b16beef) = (y div z), 'Wrong uint32 division by $b16beef for y=' + hexstr(y,sizeof(y)*2) + ' z=' + hexstr(z, sizeof(z)*2));
|
|
end;
|
|
writeln('Success.');
|
|
end.
|
|
|