int64.inc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1998 by the Free Pascal development team
  5. This file contains some helper routines for int64 and qword
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$Q- no overflow checking }
  13. {$R- no range checking }
  14. type
  15. qwordrec = packed record
  16. low : cardinal;
  17. high : cardinal;
  18. end;
  19. function count_leading_zero(q : qword) : longint;
  20. var
  21. r,i : longint;
  22. begin
  23. r:=0;
  24. for i:=0 to 31 do
  25. begin
  26. if (qwordrec(q).high and ($80000000 shr i))<>0 then
  27. begin
  28. count_leading_zero:=r;
  29. exit;
  30. end;
  31. inc(r);
  32. end;
  33. for i:=0 to 31 do
  34. begin
  35. if (qwordrec(q).low and ($80000000 shr i))<>0 then
  36. begin
  37. count_leading_zero:=r;
  38. exit;
  39. end;
  40. inc(r);
  41. end;
  42. count_leading_zero:=r;
  43. end;
  44. function divqword(z,n : qword) : qword;safecall;
  45. begin
  46. end;
  47. function divint64(z,n : int64) : int64;safecall;
  48. var
  49. sign : boolean;
  50. q1,q2,q3 : qword;
  51. begin
  52. sign:=false;
  53. if z<0 then
  54. begin
  55. sign:=not(sign);
  56. q1:=qword(-z);
  57. end
  58. else
  59. q1:=z;
  60. if q<0 then
  61. begin
  62. sign:=not(sign);
  63. q2:=qword(-q);
  64. end
  65. else
  66. q2:=q;
  67. { is coded by the compiler as call to divqword }
  68. q3:=q1 div q2;
  69. if sign then
  70. divint64:=-q3
  71. else
  72. divint64:=q3;
  73. end;
  74. { multiplies two qwords }
  75. function mulqword(f1,f2 : qword;checkoverflow : boolean) : qword;safecall;
  76. var
  77. res,bitpos : qword;
  78. l : longint;
  79. begin
  80. res:=0;
  81. bitpos:=1;
  82. { we can't write qword constants directly :( }
  83. bitpos64:=1 shl 63;
  84. for l:=0 to 63 do
  85. begin
  86. if (f2 and bitpos)<>0 then
  87. if checkoverflow then
  88. {$Q+}
  89. res:=res+f1
  90. {$Q-}
  91. else
  92. res:=res+f1;
  93. if ((f1 and bitpos64)<>0) and checkoverflow then
  94. int_overflow;
  95. f1:=f1 shl 1;
  96. bitpos:=bitpos shl 1;
  97. end;
  98. end;
  99. { multiplies two int64 ....
  100. fpuint64 = false:
  101. ... using the the qword multiplication
  102. fpuint64 = true:
  103. ... using the comp multiplication
  104. }
  105. function mulint64(f1,f2 : int64;checkoverflow : boolean) : int64;safecall;
  106. var
  107. sign : boolean;
  108. q1,q2,q3 : qword;
  109. begin
  110. sign:=false;
  111. if f1<0 then
  112. begin
  113. sign:=not(sign);
  114. q1:=qword(-f1);
  115. end
  116. else
  117. q1:=f1;
  118. if f2<0 then
  119. begin
  120. sign:=not(sign);
  121. q2:=qword(-f2);
  122. end
  123. else
  124. q2:=f2;
  125. { the q1*q2 is coded as call to mulqword }
  126. if checkoverflow then
  127. {$Q+}
  128. q3:=q1*q2
  129. else
  130. {$Q-}
  131. q3:=q1*q2
  132. if sign then
  133. mulint64:=-q3
  134. else
  135. mulint64:=q3;
  136. end;
  137. procedure int_str(value : qword;var s : string);
  138. var
  139. hs : string;
  140. begin
  141. hs:='';
  142. repeat
  143. hs:=chr(longint(value mod 10)+48)+hs;
  144. value:=value div 10;
  145. until value=0;
  146. s:=hs;
  147. end;
  148. procedure int_str(value : int64;var s : string);
  149. var
  150. hs : string;
  151. q : qword;
  152. begin
  153. if value<0 then
  154. begin
  155. q:=qword(-value);
  156. int_str(q,hs);
  157. s:='-'+hs;
  158. end
  159. else
  160. int_str(qword(value),s);
  161. end;
  162. {
  163. $Log$
  164. Revision 1.2 1999-01-06 12:25:03 florian
  165. * naming for str(...) routines inserted
  166. * don't know what in int64 changed
  167. Revision 1.1 1998/12/12 12:15:41 florian
  168. + first implementation
  169. }