Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenlargeint.c
Go to the documentation of this file.
00001 /* COPYRIGHT: See COPYING in the top level directory 00002 * PROJECT: ReactOS system libraries 00003 * FILE: lib/rtl/largeint.c 00004 * PURPOSE: Large integer operations 00005 * PROGRAMMERS: 00006 */ 00007 00008 /* INCLUDES *****************************************************************/ 00009 00010 #include <rtl.h> 00011 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* FUNCTIONS *****************************************************************/ 00016 00017 /* HACK: ld is too stupid to understand that we need the functions 00018 when we export them, so we force it to be linked this way. */ 00019 #ifdef __GNUC__ 00020 #undef RtlUshortByteSwap 00021 USHORT FASTCALL RtlUshortByteSwap(USHORT Source); 00022 PVOID Dummy = RtlUshortByteSwap; 00023 #endif 00024 00025 /* 00026 * @implemented 00027 */ 00028 LARGE_INTEGER 00029 NTAPI 00030 RtlConvertLongToLargeInteger ( 00031 LONG SignedInteger 00032 ) 00033 { 00034 LARGE_INTEGER RC; 00035 00036 RC.QuadPart = SignedInteger; 00037 00038 return RC; 00039 } 00040 00041 /* 00042 * @implemented 00043 */ 00044 LARGE_INTEGER 00045 NTAPI 00046 RtlConvertUlongToLargeInteger ( 00047 ULONG UnsignedInteger 00048 ) 00049 { 00050 LARGE_INTEGER RC; 00051 00052 RC.QuadPart = UnsignedInteger; 00053 00054 return RC; 00055 } 00056 00057 /* 00058 * @implemented 00059 */ 00060 LARGE_INTEGER 00061 NTAPI 00062 RtlEnlargedIntegerMultiply ( 00063 LONG Multiplicand, 00064 LONG Multiplier 00065 ) 00066 { 00067 LARGE_INTEGER RC; 00068 00069 RC.QuadPart = (LONGLONG) Multiplicand * Multiplier; 00070 00071 return RC; 00072 } 00073 00074 /* 00075 * @implemented 00076 */ 00077 ULONG 00078 NTAPI 00079 RtlEnlargedUnsignedDivide ( 00080 ULARGE_INTEGER Dividend, 00081 ULONG Divisor, 00082 PULONG Remainder 00083 ) 00084 { 00085 if (Remainder) 00086 *Remainder = (ULONG)(Dividend.QuadPart % Divisor); 00087 00088 return (ULONG)(Dividend.QuadPart / Divisor); 00089 } 00090 00091 /* 00092 * @implemented 00093 */ 00094 LARGE_INTEGER 00095 NTAPI 00096 RtlEnlargedUnsignedMultiply ( 00097 ULONG Multiplicand, 00098 ULONG Multiplier 00099 ) 00100 { 00101 LARGE_INTEGER RC; 00102 00103 RC.QuadPart = (ULONGLONG) Multiplicand * Multiplier; 00104 00105 return RC; 00106 } 00107 00108 /* 00109 * @implemented 00110 */ 00111 LARGE_INTEGER 00112 NTAPI 00113 RtlExtendedIntegerMultiply ( 00114 LARGE_INTEGER Multiplicand, 00115 LONG Multiplier 00116 ) 00117 { 00118 LARGE_INTEGER RC; 00119 00120 RC.QuadPart = Multiplicand.QuadPart * Multiplier; 00121 00122 return RC; 00123 } 00124 00125 /* 00126 * @implemented 00127 */ 00128 LARGE_INTEGER 00129 NTAPI 00130 RtlExtendedLargeIntegerDivide ( 00131 LARGE_INTEGER Dividend, 00132 ULONG Divisor, 00133 PULONG Remainder 00134 ) 00135 { 00136 LARGE_INTEGER RC; 00137 00138 if (Remainder) 00139 *Remainder = (ULONG)(Dividend.QuadPart % Divisor); 00140 00141 RC.QuadPart = Dividend.QuadPart / Divisor; 00142 00143 return RC; 00144 } 00145 00146 00147 /****************************************************************************** 00148 * RtlExtendedMagicDivide 00149 * 00150 * Allows replacing a division by a longlong constant with a multiplication by 00151 * the inverse constant. 00152 * 00153 * RETURNS 00154 * (Dividend * MagicDivisor) >> (64 + ShiftCount) 00155 * 00156 * NOTES 00157 * If the divisor of a division is constant, the constants MagicDivisor and 00158 * shift must be chosen such that 00159 * MagicDivisor = 2^(64 + ShiftCount) / Divisor. 00160 * 00161 * Then we have RtlExtendedMagicDivide(Dividend,MagicDivisor,ShiftCount) == 00162 * Dividend * MagicDivisor / 2^(64 + ShiftCount) == Dividend / Divisor. 00163 * 00164 * The Parameter MagicDivisor although defined as LONGLONG is used as 00165 * ULONGLONG. 00166 */ 00167 00168 #define LOWER_32(A) ((A) & 0xffffffff) 00169 #define UPPER_32(A) ((A) >> 32) 00170 00171 /* 00172 * @implemented 00173 */ 00174 LARGE_INTEGER NTAPI 00175 RtlExtendedMagicDivide (LARGE_INTEGER Dividend, 00176 LARGE_INTEGER MagicDivisor, 00177 CCHAR ShiftCount) 00178 { 00179 ULONGLONG dividend_high; 00180 ULONGLONG dividend_low; 00181 ULONGLONG inverse_divisor_high; 00182 ULONGLONG inverse_divisor_low; 00183 ULONGLONG ah_bl; 00184 ULONGLONG al_bh; 00185 LARGE_INTEGER result; 00186 BOOLEAN positive; 00187 00188 if (Dividend.QuadPart < 0) 00189 { 00190 dividend_high = UPPER_32((ULONGLONG) -Dividend.QuadPart); 00191 dividend_low = LOWER_32((ULONGLONG) -Dividend.QuadPart); 00192 positive = FALSE; 00193 } 00194 else 00195 { 00196 dividend_high = UPPER_32((ULONGLONG) Dividend.QuadPart); 00197 dividend_low = LOWER_32((ULONGLONG) Dividend.QuadPart); 00198 positive = TRUE; 00199 } 00200 inverse_divisor_high = UPPER_32((ULONGLONG) MagicDivisor.QuadPart); 00201 inverse_divisor_low = LOWER_32((ULONGLONG) MagicDivisor.QuadPart); 00202 00203 ah_bl = dividend_high * inverse_divisor_low; 00204 al_bh = dividend_low * inverse_divisor_high; 00205 00206 result.QuadPart = 00207 (LONGLONG) ((dividend_high * inverse_divisor_high + 00208 UPPER_32(ah_bl) + 00209 UPPER_32(al_bh) + 00210 UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) + 00211 UPPER_32(dividend_low * inverse_divisor_low))) >> ShiftCount); 00212 if (!positive) 00213 { 00214 result.QuadPart = -result.QuadPart; 00215 } 00216 00217 return result; 00218 } 00219 00220 00221 /* 00222 * @implemented 00223 */ 00224 LARGE_INTEGER 00225 NTAPI 00226 RtlLargeIntegerAdd ( 00227 LARGE_INTEGER Addend1, 00228 LARGE_INTEGER Addend2 00229 ) 00230 { 00231 LARGE_INTEGER RC; 00232 00233 RC.QuadPart = Addend1.QuadPart + Addend2.QuadPart; 00234 00235 return RC; 00236 } 00237 00238 /* 00239 * @implemented 00240 */ 00241 LARGE_INTEGER 00242 NTAPI 00243 RtlLargeIntegerArithmeticShift ( 00244 LARGE_INTEGER LargeInteger, 00245 CCHAR ShiftCount 00246 ) 00247 { 00248 LARGE_INTEGER RC; 00249 CHAR Shift; 00250 00251 Shift = ShiftCount % 64; 00252 00253 if (Shift < 32) 00254 { 00255 RC.QuadPart = LargeInteger.QuadPart >> Shift; 00256 } 00257 else 00258 { 00259 /* copy the sign bit */ 00260 RC.u.HighPart = (LargeInteger.u.HighPart & 0x80000000); 00261 RC.u.LowPart = LargeInteger.u.HighPart >> Shift; 00262 } 00263 00264 return RC; 00265 } 00266 00267 /* 00268 * @implemented 00269 */ 00270 LARGE_INTEGER 00271 NTAPI 00272 RtlLargeIntegerDivide ( 00273 LARGE_INTEGER Dividend, 00274 LARGE_INTEGER Divisor, 00275 PLARGE_INTEGER Remainder 00276 ) 00277 { 00278 LARGE_INTEGER RC; 00279 00280 if (Remainder) 00281 Remainder->QuadPart = Dividend.QuadPart % Divisor.QuadPart; 00282 00283 RC.QuadPart = Dividend.QuadPart / Divisor.QuadPart; 00284 00285 return RC; 00286 } 00287 00288 /* 00289 * @implemented 00290 */ 00291 LARGE_INTEGER 00292 NTAPI 00293 RtlLargeIntegerNegate ( 00294 LARGE_INTEGER Subtrahend 00295 ) 00296 { 00297 LARGE_INTEGER RC; 00298 00299 RC.QuadPart = - Subtrahend.QuadPart; 00300 00301 return RC; 00302 } 00303 00304 /* 00305 * @implemented 00306 */ 00307 LARGE_INTEGER 00308 NTAPI 00309 RtlLargeIntegerShiftLeft ( 00310 LARGE_INTEGER LargeInteger, 00311 CCHAR ShiftCount 00312 ) 00313 { 00314 LARGE_INTEGER RC; 00315 CCHAR Shift; 00316 00317 Shift = ShiftCount % 64; 00318 RC.QuadPart = LargeInteger.QuadPart << Shift; 00319 00320 return RC; 00321 } 00322 00323 /* 00324 * @implemented 00325 */ 00326 LARGE_INTEGER 00327 NTAPI 00328 RtlLargeIntegerShiftRight ( 00329 LARGE_INTEGER LargeInteger, 00330 CCHAR ShiftCount 00331 ) 00332 { 00333 LARGE_INTEGER RC; 00334 CCHAR Shift; 00335 00336 Shift = ShiftCount % 64; 00337 RC.QuadPart = LargeInteger.QuadPart >> Shift; 00338 00339 return RC; 00340 } 00341 00342 /* 00343 * @implemented 00344 */ 00345 LARGE_INTEGER 00346 NTAPI 00347 RtlLargeIntegerSubtract ( 00348 LARGE_INTEGER Minuend, 00349 LARGE_INTEGER Subtrahend 00350 ) 00351 { 00352 LARGE_INTEGER RC; 00353 00354 RC.QuadPart = Minuend.QuadPart - Subtrahend.QuadPart; 00355 00356 return RC; 00357 } 00358 00359 /* EOF */ Generated on Sun May 27 2012 04:36:22 for ReactOS by
1.7.6.1
|