tmoddiv2.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. program mymodtest;
  2. {$MODE DELPHI}
  3. {$ASSERTIONS ON}
  4. // Pascal implementation of signed modulus by power of 2 constant algorithm
  5. function my_modulus(x, m : integer) : integer;
  6. var
  7. temp, mask1, mask2 : integer;
  8. begin
  9. m := abs(m-1);
  10. temp := x and m;
  11. if (x < 0) then begin // = sign bit
  12. mask2 := -1;
  13. end else begin
  14. mask2 := 0;
  15. end;
  16. if (temp <> 0) then begin // note: temp >= 0
  17. mask1 := -1;
  18. end else begin
  19. mask1 := 0;
  20. end;
  21. my_modulus := temp or ((not m) and mask1 and mask2);
  22. end;
  23. function i32_modulus(x, m : integer) : integer;
  24. var
  25. temp : integer;
  26. begin
  27. temp := x div m;
  28. i32_modulus := x - (temp*m);
  29. end;
  30. function u32_modulus(x, m : dword) : dword;
  31. var
  32. temp : dword;
  33. begin
  34. temp := x div m;
  35. u32_modulus := x - (temp*m);
  36. end;
  37. var
  38. i : integer;
  39. j, k : longint;
  40. res, res2 : longint;
  41. y, z : dword;
  42. begin
  43. randseed := 1; // just take any, but repeatable
  44. write('positive int32 division test...');
  45. for i := -10000 to 10000 do begin
  46. j := random(high(integer));
  47. if (random(2) = 1) then j := -j;
  48. k := 19;
  49. 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));
  50. end;
  51. writeln('Success.');
  52. write('Negative int32 division test...');
  53. for i := -10000 to 10000 do begin
  54. j := random(high(integer));
  55. if (random(2) = 1) then j := -j;
  56. k := -19;
  57. 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));
  58. end;
  59. writeln('Success.');
  60. write('positive int32 division test...');
  61. for i := -10000 to 10000 do begin
  62. j := random(high(integer));
  63. if (random(2) = 1) then j := -j;
  64. k := 3;
  65. 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));
  66. end;
  67. writeln('Success.');
  68. write('Negative int32 division test...');
  69. for i := -10000 to 10000 do begin
  70. j := random(high(integer));
  71. if (random(2) = 1) then j := -j;
  72. k := -3;
  73. 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));
  74. end;
  75. writeln('Success.');
  76. write('positive int32 division test...');
  77. for i := -10000 to 10000 do begin
  78. j := random(high(integer));
  79. if (random(2) = 1) then j := -j;
  80. k := 7;
  81. 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));
  82. end;
  83. writeln('Success.');
  84. write('Negative int32 division test...');
  85. for i := -10000 to 10000 do begin
  86. j := random(high(integer));
  87. if (random(2) = 1) then j := -j;
  88. k := -7;
  89. 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));
  90. end;
  91. writeln('Success.');
  92. write('positive int32 division test...');
  93. for i := -10000 to 10000 do begin
  94. j := random(high(integer));
  95. if (random(2) = 1) then j := -j;
  96. k := 5;
  97. 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));
  98. end;
  99. writeln('Success.');
  100. write('Negative int32 division test...');
  101. for i := -10000 to 10000 do begin
  102. j := random(high(integer));
  103. if (random(2) = 1) then j := -j;
  104. k := -5;
  105. 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));
  106. end;
  107. writeln('Success.');
  108. write('positive int32 division test...');
  109. for i := -10000 to 10000 do begin
  110. j := random(high(integer));
  111. if (random(2) = 1) then j := -j;
  112. k := 512;
  113. 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));
  114. end;
  115. writeln('Success.');
  116. write('Negative int32 division test...');
  117. for i := -10000 to 10000 do begin
  118. j := random(high(integer));
  119. if (random(2) = 1) then j := -j;
  120. k := -512;
  121. 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));
  122. end;
  123. writeln('Success.');
  124. //-----------------------------------------------------------------
  125. write('positive int32 modulus test (19)...');
  126. for i := -10000 to 10000 do begin
  127. j := random(high(integer));
  128. if (random(2) = 1) then j := -j;
  129. k := 19;
  130. 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));
  131. end;
  132. writeln('Success.');
  133. write('Negative int32 modulus test (-19)...');
  134. for i := -10000 to 10000 do begin
  135. j := random(high(integer));
  136. if (random(2) = 1) then j := -j;
  137. k := -19;
  138. res := j mod -19;
  139. res2 := i32_modulus(j, k);
  140. 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));
  141. end;
  142. writeln('Success.');
  143. write('positive int32 modulus test (3)...');
  144. for i := -10000 to 10000 do begin
  145. j := random(high(integer));
  146. if (random(2) = 1) then j := -j;
  147. k := 3;
  148. 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));
  149. end;
  150. writeln('Success.');
  151. write('Negative int32 modulus test (-3)...');
  152. for i := -10000 to 10000 do begin
  153. j := random(high(integer));
  154. if (random(2) = 1) then j := -j;
  155. k := -3;
  156. res := j mod -3;
  157. res2 := i32_modulus(j, k);
  158. 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));
  159. end;
  160. writeln('Success.');
  161. write('positive int32 modulus test (5)...');
  162. for i := -10000 to 10000 do begin
  163. j := random(high(integer));
  164. if (random(2) = 1) then j := -j;
  165. k := 5;
  166. 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));
  167. end;
  168. writeln('Success.');
  169. write('Negative int32 modulus test (-5)...');
  170. for i := -10000 to 10000 do begin
  171. j := random(high(integer));
  172. if (random(2) = 1) then j := -j;
  173. k := -5;
  174. res := j mod -5;
  175. res2 := i32_modulus(j, k);
  176. 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));
  177. end;
  178. writeln('Success.');
  179. write('positive int32 modulus test (7)...');
  180. for i := -10000 to 10000 do begin
  181. j := random(high(integer));
  182. if (random(2) = 1) then j := -j;
  183. k := 7;
  184. 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));
  185. end;
  186. writeln('Success.');
  187. write('Negative int32 modulus test (-7)...');
  188. for i := -10000 to 10000 do begin
  189. j := random(high(integer));
  190. if (random(2) = 1) then j := -j;
  191. k := -7;
  192. res := j mod -7;
  193. res2 := i32_modulus(j, k);
  194. 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));
  195. end;
  196. writeln('Success.');
  197. write('positive int32 modulus test (512)...');
  198. for i := -10000 to 10000 do begin
  199. j := random(high(integer));
  200. if (random(2) = 1) then j := -j;
  201. k := 512;
  202. 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));
  203. end;
  204. writeln('Success.');
  205. write('Negative int32 modulus test (-512)...');
  206. for i := -10000 to 10000 do begin
  207. j := random(high(integer));
  208. if (random(2) = 1) then j := -j;
  209. k := -512;
  210. res := j mod -512;
  211. res2 := i32_modulus(j, k);
  212. 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));
  213. end;
  214. writeln('Success.');
  215. write('positive uint32 division test (19)...');
  216. for i := -10000 to 10000 do begin
  217. y := random(high(integer));
  218. if (random(2) = 1) then y := 2 * y;
  219. z := 19;
  220. 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));
  221. end;
  222. writeln('Success.');
  223. write('positive uint32 modulus test (19)...');
  224. for i := -10000 to 10000 do begin
  225. y := random(high(integer));
  226. if (random(2) = 1) then y := 2 * y;
  227. z := 19;
  228. 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));
  229. end;
  230. writeln('Success.');
  231. write('positive uint32 division test (3)...');
  232. for i := -10000 to 10000 do begin
  233. y := random(high(integer));
  234. if (random(2) = 1) then y := 2 * y;
  235. z := 3;
  236. 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));
  237. end;
  238. writeln('Success.');
  239. write('positive uint32 modulus test (3)...');
  240. for i := -10000 to 10000 do begin
  241. y := random(high(integer));
  242. if (random(2) = 1) then y := 2 * y;
  243. z := 3;
  244. 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));
  245. end;
  246. writeln('Success.');
  247. write('positive uint32 division test (5)...');
  248. for i := -10000 to 10000 do begin
  249. y := random(high(integer));
  250. if (random(2) = 1) then y := 2 * y;
  251. z := 5;
  252. 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));
  253. end;
  254. writeln('Success.');
  255. write('positive uint32 modulus test (5)...');
  256. for i := -10000 to 10000 do begin
  257. y := random(high(integer));
  258. if (random(2) = 1) then y := 2 * y;
  259. z := 5;
  260. 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));
  261. end;
  262. writeln('Success.');
  263. write('positive uint32 division test...');
  264. for i := -10000 to 10000 do begin
  265. y := random(high(integer));
  266. if (random(2) = 1) then y := 2 * y;
  267. z := 7;
  268. 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));
  269. end;
  270. writeln('Success.');
  271. write('positive uint32 modulus test...');
  272. for i := -10000 to 10000 do begin
  273. y := random(high(integer));
  274. if (random(2) = 1) then y := 2 * y;
  275. z := 7;
  276. 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));
  277. end;
  278. writeln('Success.');
  279. write('positive uint32 division test...');
  280. for i := -10000 to 10000 do begin
  281. y := random(high(integer));
  282. if (random(2) = 1) then y := 2 * y;
  283. z := 512;
  284. 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));
  285. end;
  286. writeln('Success.');
  287. write('positive uint32 modulus test...');
  288. for i := -10000 to 10000 do begin
  289. y := random(high(integer));
  290. if (random(2) = 1) then y := 2 * y;
  291. z := 512;
  292. 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));
  293. end;
  294. writeln('Success.');
  295. { extra test for div by constant optimization }
  296. write('positive uint32 division test...');
  297. for i := -10000 to 10000 do begin
  298. y := random(high(integer));
  299. if (random(2) = 1) then y := 2 * y;
  300. z := $deadbeef;
  301. 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));
  302. end;
  303. writeln('Success.');
  304. write('positive uint32 division test...');
  305. for i := -10000 to 10000 do begin
  306. y := random(high(integer));
  307. if (random(2) = 1) then y := 2 * y;
  308. z := $b16beef;
  309. 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));
  310. end;
  311. writeln('Success.');
  312. end.