ReactOS  0.4.14-dev-57-g333b8f1
largeint.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: lib/rtl/largeint.c
5  * PURPOSE: Large integer operations
6  * PROGRAMMERS:
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include <rtl.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* FUNCTIONS *****************************************************************/
17 
18 /* HACK: ld is too stupid to understand that we need the functions
19  when we export them, so we force it to be linked this way. */
20 #ifdef __GNUC__
21 #undef RtlUshortByteSwap
23 PVOID Dummy = RtlUshortByteSwap;
24 #endif
25 
26 /*
27  * @implemented
28  */
30 NTAPI
32  LONG SignedInteger
33 )
34 {
35  LARGE_INTEGER RC;
36 
37  RC.QuadPart = SignedInteger;
38 
39  return RC;
40 }
41 
42 /*
43  * @implemented
44  */
46 NTAPI
48  ULONG UnsignedInteger
49 )
50 {
51  LARGE_INTEGER RC;
52 
53  RC.QuadPart = UnsignedInteger;
54 
55  return RC;
56 }
57 
58 /*
59  * @implemented
60  */
62 NTAPI
64  LONG Multiplicand,
65  LONG Multiplier
66 )
67 {
68  LARGE_INTEGER RC;
69 
70  RC.QuadPart = (LONGLONG) Multiplicand * Multiplier;
71 
72  return RC;
73 }
74 
75 /*
76  * @implemented
77  */
78 ULONG
79 NTAPI
81  ULARGE_INTEGER Dividend,
82  ULONG Divisor,
84 )
85 {
86  if (Remainder)
87  *Remainder = (ULONG)(Dividend.QuadPart % Divisor);
88 
89  return (ULONG)(Dividend.QuadPart / Divisor);
90 }
91 
92 /*
93  * @implemented
94  */
96 NTAPI
98  ULONG Multiplicand,
99  ULONG Multiplier
100 )
101 {
102  LARGE_INTEGER RC;
103 
104  RC.QuadPart = (ULONGLONG) Multiplicand * Multiplier;
105 
106  return RC;
107 }
108 
109 /*
110  * @implemented
111  */
113 NTAPI
115  LARGE_INTEGER Multiplicand,
116  LONG Multiplier
117 )
118 {
119  LARGE_INTEGER RC;
120 
121  RC.QuadPart = Multiplicand.QuadPart * Multiplier;
122 
123  return RC;
124 }
125 
126 /*
127  * @implemented
128  */
130 NTAPI
132  LARGE_INTEGER Dividend,
133  ULONG Divisor,
135 )
136 {
137  LARGE_INTEGER RC;
138 
139  if (Remainder)
140  *Remainder = (ULONG)(Dividend.QuadPart % Divisor);
141 
142  RC.QuadPart = Dividend.QuadPart / Divisor;
143 
144  return RC;
145 }
146 
147 
148 /******************************************************************************
149  * RtlExtendedMagicDivide
150  *
151  * Allows replacing a division by a longlong constant with a multiplication by
152  * the inverse constant.
153  *
154  * RETURNS
155  * (Dividend * MagicDivisor) >> (64 + ShiftCount)
156  *
157  * NOTES
158  * If the divisor of a division is constant, the constants MagicDivisor and
159  * shift must be chosen such that
160  * MagicDivisor = 2^(64 + ShiftCount) / Divisor.
161  *
162  * Then we have RtlExtendedMagicDivide(Dividend,MagicDivisor,ShiftCount) ==
163  * Dividend * MagicDivisor / 2^(64 + ShiftCount) == Dividend / Divisor.
164  *
165  * The Parameter MagicDivisor although defined as LONGLONG is used as
166  * ULONGLONG.
167  */
168 
169 #define LOWER_32(A) ((A) & 0xffffffff)
170 #define UPPER_32(A) ((A) >> 32)
171 
172 /*
173  * @implemented
174  */
177  LARGE_INTEGER MagicDivisor,
178  CCHAR ShiftCount)
179 {
180  ULONGLONG dividend_high;
181  ULONGLONG dividend_low;
182  ULONGLONG inverse_divisor_high;
183  ULONGLONG inverse_divisor_low;
184  ULONGLONG ah_bl;
185  ULONGLONG al_bh;
188 
189  if (Dividend.QuadPart < 0)
190  {
191  dividend_high = UPPER_32((ULONGLONG) -Dividend.QuadPart);
192  dividend_low = LOWER_32((ULONGLONG) -Dividend.QuadPart);
193  positive = FALSE;
194  }
195  else
196  {
197  dividend_high = UPPER_32((ULONGLONG) Dividend.QuadPart);
198  dividend_low = LOWER_32((ULONGLONG) Dividend.QuadPart);
199  positive = TRUE;
200  }
201  inverse_divisor_high = UPPER_32((ULONGLONG) MagicDivisor.QuadPart);
202  inverse_divisor_low = LOWER_32((ULONGLONG) MagicDivisor.QuadPart);
203 
204  ah_bl = dividend_high * inverse_divisor_low;
205  al_bh = dividend_low * inverse_divisor_high;
206 
207  result.QuadPart =
208  (LONGLONG) ((dividend_high * inverse_divisor_high +
209  UPPER_32(ah_bl) +
210  UPPER_32(al_bh) +
211  UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) +
212  UPPER_32(dividend_low * inverse_divisor_low))) >> ShiftCount);
213  if (!positive)
214  {
215  result.QuadPart = -result.QuadPart;
216  }
217 
218  return result;
219 }
220 
221 
222 /*
223  * @implemented
224  */
226 NTAPI
228  LARGE_INTEGER Addend1,
230 )
231 {
232  LARGE_INTEGER RC;
233 
234  RC.QuadPart = Addend1.QuadPart + Addend2.QuadPart;
235 
236  return RC;
237 }
238 
239 /*
240  * @implemented
241  */
243 NTAPI
245  LARGE_INTEGER LargeInteger,
246  CCHAR ShiftCount
247 )
248 {
249  LARGE_INTEGER RC;
250  CHAR Shift;
251 
252  Shift = ShiftCount % 64;
253 
254  if (Shift < 32)
255  {
256  RC.QuadPart = LargeInteger.QuadPart >> Shift;
257  }
258  else
259  {
260  /* copy the sign bit */
261  RC.u.HighPart = (LargeInteger.u.HighPart & 0x80000000);
262  RC.u.LowPart = LargeInteger.u.HighPart >> Shift;
263  }
264 
265  return RC;
266 }
267 
268 /*
269  * @implemented
270  */
272 NTAPI
274  LARGE_INTEGER Dividend,
277 )
278 {
279  LARGE_INTEGER RC;
280 
281  if (Remainder)
283 
284  RC.QuadPart = Dividend.QuadPart / Divisor.QuadPart;
285 
286  return RC;
287 }
288 
289 /*
290  * @implemented
291  */
293 NTAPI
295  LARGE_INTEGER Subtrahend
296 )
297 {
298  LARGE_INTEGER RC;
299 
300  RC.QuadPart = - Subtrahend.QuadPart;
301 
302  return RC;
303 }
304 
305 /*
306  * @implemented
307  */
309 NTAPI
311  LARGE_INTEGER LargeInteger,
312  CCHAR ShiftCount
313 )
314 {
315  LARGE_INTEGER RC;
316  CCHAR Shift;
317 
318  Shift = ShiftCount % 64;
319  RC.QuadPart = LargeInteger.QuadPart << Shift;
320 
321  return RC;
322 }
323 
324 /*
325  * @implemented
326  */
328 NTAPI
330  LARGE_INTEGER LargeInteger,
331  CCHAR ShiftCount
332 )
333 {
334  LARGE_INTEGER RC;
335  CCHAR Shift;
336 
337  Shift = ShiftCount % 64;
338  RC.QuadPart = LargeInteger.QuadPart >> Shift;
339 
340  return RC;
341 }
342 
343 /*
344  * @implemented
345  */
347 NTAPI
349  LARGE_INTEGER Minuend,
350  LARGE_INTEGER Subtrahend
351 )
352 {
353  LARGE_INTEGER RC;
354 
355  RC.QuadPart = Minuend.QuadPart - Subtrahend.QuadPart;
356 
357  return RC;
358 }
359 
360 /* EOF */
_In_ LARGE_INTEGER Addend2
Definition: rtlfuncs.h:3089
#define TRUE
Definition: types.h:120
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3199
char CHAR
Definition: xmlstorage.h:175
#define FASTCALL
Definition: nt_native.h:50
LARGE_INTEGER NTAPI RtlEnlargedUnsignedMultiply(ULONG Multiplicand, ULONG Multiplier)
Definition: largeint.c:97
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
long LONG
Definition: pedump.c:60
struct _LARGE_INTEGER::@2201 u
LARGE_INTEGER NTAPI RtlExtendedLargeIntegerDivide(LARGE_INTEGER Dividend, ULONG Divisor, PULONG Remainder)
Definition: largeint.c:131
unsigned char BOOLEAN
LARGE_INTEGER NTAPI RtlLargeIntegerArithmeticShift(LARGE_INTEGER LargeInteger, CCHAR ShiftCount)
Definition: largeint.c:244
int64_t LONGLONG
Definition: typedefs.h:66
char CCHAR
Definition: typedefs.h:50
uint64_t ULONGLONG
Definition: typedefs.h:65
LARGE_INTEGER NTAPI RtlEnlargedIntegerMultiply(LONG Multiplicand, LONG Multiplier)
Definition: largeint.c:63
LARGE_INTEGER NTAPI RtlLargeIntegerNegate(LARGE_INTEGER Subtrahend)
Definition: largeint.c:294
#define UPPER_32(A)
Definition: largeint.c:170
LARGE_INTEGER NTAPI RtlConvertLongToLargeInteger(LONG SignedInteger)
Definition: largeint.c:31
LARGE_INTEGER NTAPI RtlLargeIntegerSubtract(LARGE_INTEGER Minuend, LARGE_INTEGER Subtrahend)
Definition: largeint.c:348
LARGE_INTEGER NTAPI RtlExtendedMagicDivide(LARGE_INTEGER Dividend, LARGE_INTEGER MagicDivisor, CCHAR ShiftCount)
Definition: largeint.c:176
LARGE_INTEGER NTAPI RtlExtendedIntegerMultiply(LARGE_INTEGER Multiplicand, LONG Multiplier)
Definition: largeint.c:114
unsigned short USHORT
Definition: pedump.c:61
LARGE_INTEGER NTAPI RtlConvertUlongToLargeInteger(ULONG UnsignedInteger)
Definition: largeint.c:47
LARGE_INTEGER NTAPI RtlLargeIntegerShiftLeft(LARGE_INTEGER LargeInteger, CCHAR ShiftCount)
Definition: largeint.c:310
_In_ ULONG Shift
Definition: rtlfuncs.h:2683
unsigned int * PULONG
Definition: retypes.h:1
#define LOWER_32(A)
Definition: largeint.c:169
ULONG NTAPI RtlEnlargedUnsignedDivide(ULARGE_INTEGER Dividend, ULONG Divisor, PULONG Remainder)
Definition: largeint.c:80
LARGE_INTEGER NTAPI RtlLargeIntegerDivide(LARGE_INTEGER Dividend, LARGE_INTEGER Divisor, PLARGE_INTEGER Remainder)
Definition: largeint.c:273
LARGE_INTEGER NTAPI RtlLargeIntegerAdd(LARGE_INTEGER Addend1, LARGE_INTEGER Addend2)
Definition: largeint.c:227
_In_ LARGE_INTEGER Divisor
Definition: rtlfuncs.h:3046
unsigned int ULONG
Definition: retypes.h:1
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
LARGE_INTEGER NTAPI RtlLargeIntegerShiftRight(LARGE_INTEGER LargeInteger, CCHAR ShiftCount)
Definition: largeint.c:329
GLuint64EXT * result
Definition: glext.h:11304
LONGLONG QuadPart
Definition: typedefs.h:112
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3046
Definition: unary.h:15