ReactOS 0.4.16-dev-258-g81860b4
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
24#endif
25
26/*
27 * @implemented
28 */
32 LONG SignedInteger
33)
34{
36
37 RC.QuadPart = SignedInteger;
38
39 return RC;
40}
41
42/*
43 * @implemented
44 */
48 ULONG UnsignedInteger
49)
50{
52
53 RC.QuadPart = UnsignedInteger;
54
55 return RC;
56}
57
58/*
59 * @implemented
60 */
64 LONG Multiplicand,
65 LONG Multiplier
66)
67{
69
70 RC.QuadPart = (LONGLONG) Multiplicand * Multiplier;
71
72 return RC;
73}
74
75/*
76 * @implemented
77 */
81 ULARGE_INTEGER Dividend,
84)
85{
86 if (Remainder)
87 *Remainder = (ULONG)(Dividend.QuadPart % Divisor);
88
89 return (ULONG)(Dividend.QuadPart / Divisor);
90}
91
92/*
93 * @implemented
94 */
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 */
113NTAPI
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 */
130NTAPI
132 LARGE_INTEGER Dividend,
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 */
226NTAPI
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 */
243NTAPI
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 */
272NTAPI
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 */
293NTAPI
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 */
309NTAPI
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 */
328NTAPI
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 */
347NTAPI
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 */
unsigned char BOOLEAN
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
GLuint64EXT * result
Definition: glext.h:11304
LARGE_INTEGER NTAPI RtlEnlargedIntegerMultiply(LONG Multiplicand, LONG Multiplier)
Definition: largeint.c:63
LARGE_INTEGER NTAPI RtlLargeIntegerShiftLeft(LARGE_INTEGER LargeInteger, CCHAR ShiftCount)
Definition: largeint.c:310
LARGE_INTEGER NTAPI RtlLargeIntegerNegate(LARGE_INTEGER Subtrahend)
Definition: largeint.c:294
LARGE_INTEGER NTAPI RtlLargeIntegerSubtract(LARGE_INTEGER Minuend, LARGE_INTEGER Subtrahend)
Definition: largeint.c:348
LARGE_INTEGER NTAPI RtlExtendedIntegerMultiply(LARGE_INTEGER Multiplicand, LONG Multiplier)
Definition: largeint.c:114
ULONG NTAPI RtlEnlargedUnsignedDivide(ULARGE_INTEGER Dividend, ULONG Divisor, PULONG Remainder)
Definition: largeint.c:80
#define UPPER_32(A)
Definition: largeint.c:170
LARGE_INTEGER NTAPI RtlExtendedMagicDivide(LARGE_INTEGER Dividend, LARGE_INTEGER MagicDivisor, CCHAR ShiftCount)
Definition: largeint.c:176
LARGE_INTEGER NTAPI RtlLargeIntegerDivide(LARGE_INTEGER Dividend, LARGE_INTEGER Divisor, PLARGE_INTEGER Remainder)
Definition: largeint.c:273
LARGE_INTEGER NTAPI RtlConvertLongToLargeInteger(LONG SignedInteger)
Definition: largeint.c:31
LARGE_INTEGER NTAPI RtlConvertUlongToLargeInteger(ULONG UnsignedInteger)
Definition: largeint.c:47
LARGE_INTEGER NTAPI RtlExtendedLargeIntegerDivide(LARGE_INTEGER Dividend, ULONG Divisor, PULONG Remainder)
Definition: largeint.c:131
#define LOWER_32(A)
Definition: largeint.c:169
LARGE_INTEGER NTAPI RtlLargeIntegerAdd(LARGE_INTEGER Addend1, LARGE_INTEGER Addend2)
Definition: largeint.c:227
LARGE_INTEGER NTAPI RtlLargeIntegerShiftRight(LARGE_INTEGER LargeInteger, CCHAR ShiftCount)
Definition: largeint.c:329
LARGE_INTEGER NTAPI RtlEnlargedUnsignedMultiply(ULONG Multiplicand, ULONG Multiplier)
Definition: largeint.c:97
LARGE_INTEGER NTAPI RtlLargeIntegerArithmeticShift(LARGE_INTEGER LargeInteger, CCHAR ShiftCount)
Definition: largeint.c:244
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
#define FASTCALL
Definition: nt_native.h:50
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: unary.h:15
uint32_t * PULONG
Definition: typedefs.h:59
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
char CCHAR
Definition: typedefs.h:51
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2302 u
_In_ ULONG Shift
Definition: rtlfuncs.h:2698
_In_ LARGE_INTEGER Divisor
Definition: rtlfuncs.h:3061
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3062
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3214
_In_ LARGE_INTEGER Addend2
Definition: rtlfuncs.h:3104
char CHAR
Definition: xmlstorage.h:175