diff options
Diffstat (limited to 'CInt64.c')
-rw-r--r-- | CInt64.c | 893 |
1 files changed, 0 insertions, 893 deletions
diff --git a/CInt64.c b/CInt64.c deleted file mode 100644 index 9b793bd..0000000 --- a/CInt64.c +++ /dev/null @@ -1,893 +0,0 @@ -#include <MacHeadersMach-O> -#include "CInt64.h" - -const CInt64 cint64_negone = {0xFFFFFFFF, 0xFFFFFFFF}; -const CInt64 cint64_zero = {0, 0}; -const CInt64 cint64_one = {0, 1}; -const CInt64 cint64_max = {0x7FFFFFFF, 0xFFFFFFFF}; -const CInt64 cint64_min = {0x80000000, 0}; - -#define SHIFT_LEFT_ONE(a, b) do { a <<= 1; if (b & 0x80000000) { a |= 1; } b <<= 1; } while(0) - -void CInt64_Init() { -} - -CInt64 CInt64_Not(CInt64 input) { - CInt64 output; - unsigned char c; - - c = (input.a == 0 && input.b == 0); - CInt64_SetLong(&output, c); - - return output; -} - -CInt64 CInt64_Inv(CInt64 input) { - CInt64 output; - output.a = ~input.a; - output.b = ~input.b; - return output; -} - -CInt64 CInt64_Add(CInt64 lhs, CInt64 rhs) { - if (lhs.b & 0x80000000) { - if (rhs.b & 0x80000000) { - lhs.b += rhs.b; - lhs.a += 1; - } else { - lhs.b += rhs.b; - if (!(lhs.b & 0x80000000)) - lhs.a += 1; - } - } else { - if (rhs.b & 0x80000000) { - lhs.b += rhs.b; - if (!(lhs.b & 0x80000000)) - lhs.a += 1; - } else { - lhs.b += rhs.b; - } - } - lhs.a += rhs.a; - return lhs; -} - -CInt64 CInt64_Neg(CInt64 input) { - CInt64 result; - result = CInt64_Add(CInt64_Inv(input), cint64_one); - return result; -} - -CInt64 CInt64_Sub(CInt64 lhs, CInt64 rhs) { - lhs = CInt64_Add(lhs, CInt64_Neg(rhs)); - return lhs; -} - -CInt64 CInt64_MulU(CInt64 lhs, CInt64 rhs) { - CInt64 result; - CInt64 work1; - unsigned long aaaa; - unsigned long bbbb; - unsigned long cccc; - unsigned long dddd; - unsigned long eeee; - - aaaa = rhs.b; - result.a = result.b = 0; - bbbb = lhs.b; - cccc = rhs.a; - dddd = rhs.b; - - while (bbbb != 0) { - if (bbbb & 1) { - work1.a = cccc; - work1.b = dddd; - result = CInt64_Add(result, work1); - } - cccc <<= 1; - if (dddd & 0x80000000) - cccc |= 1; - dddd <<= 1; - bbbb >>= 1; - } - - eeee = lhs.a; - while (eeee != 0 && aaaa != 0) { - if (eeee & 1) - result.a += aaaa; - aaaa <<= 1; - eeee >>= 1; - } - - return result; -} - -CInt64 CInt64_Mul(CInt64 lhs, CInt64 rhs) { - if (CInt64_IsNegative(&rhs)) { - if (CInt64_IsNegative(&lhs)) { - return CInt64_MulU(CInt64_Neg(lhs), CInt64_Neg(rhs)); - } - return CInt64_Neg(CInt64_MulU(lhs, CInt64_Neg(rhs))); - } - if (CInt64_IsNegative(&lhs)) { - return CInt64_Neg(CInt64_MulU(CInt64_Neg(lhs), rhs)); - } - return CInt64_MulU(lhs, rhs); -} - -void CInt64_DivMod(const CInt64 *lhs, const CInt64 *rhs, CInt64 *pDiv, CInt64 *pMod) { - unsigned char bad; - unsigned long workA; - unsigned long workB; - unsigned long leftA; - unsigned long leftB; - unsigned long rightA; - unsigned long rightB; - unsigned long outA; - unsigned long outB; - CInt64 work; - int counter; - - bad = (rhs->a == 0) && (rhs->b == 0); - if (!bad) { - workA = 0; - workB = 0; - leftA = lhs->a; - leftB = lhs->b; - rightA = rhs->a; - rightB = rhs->b; - outA = 0; - outB = 0; - counter = 0; - - do { - workA <<= 1; - if (workB & 0x80000000) - workA |= 1; - workB <<= 1; - if (leftA & 0x80000000) - workB |= 1; - leftA <<= 1; - if (leftB & 0x80000000) - leftA |= 1; - leftB <<= 1; - - outA <<= 1; - if (outB & 0x80000000) - outA |= 1; - outB <<= 1; - - if (workA <= rightA) { - if (workA != rightA) - continue; - if (workB < rightB) - continue; - } - - outB |= 1; - - work.a = workA; - work.b = workB; - work = CInt64_Sub(work, *rhs); - workA = work.a; - workB = work.b; - } while (++counter < 64); - - if (pDiv) { - pDiv->a = outA; - pDiv->b = outB; - } - if (pMod) { - pMod->a = workA; - pMod->b = workB; - } - } -} - -CInt64 CInt64_Div(CInt64 lhs, CInt64 rhs) { - CInt64 result; - if (CInt64_IsNegative(&rhs)) { - rhs = CInt64_Neg(rhs); - if (CInt64_IsNegative(&lhs)) { - lhs = CInt64_Neg(lhs); - CInt64_DivMod(&lhs, &rhs, &result, 0); - return result; - } else { - CInt64_DivMod(&lhs, &rhs, &result, 0); - return CInt64_Neg(result); - } - } else { - if (CInt64_IsNegative(&lhs)) { - lhs = CInt64_Neg(lhs); - CInt64_DivMod(&lhs, &rhs, &result, 0); - return CInt64_Neg(result); - } else { - CInt64_DivMod(&lhs, &rhs, &result, 0); - return result; - } - } -} - -CInt64 CInt64_DivU(CInt64 lhs, CInt64 rhs) { - CInt64 result; - CInt64_DivMod(&lhs, &rhs, &result, 0); - return result; -} - -CInt64 CInt64_Mod(CInt64 lhs, CInt64 rhs) { - CInt64 result; - if (CInt64_IsNegative(&lhs)) { - lhs = CInt64_Neg(lhs); - if (CInt64_IsNegative(&rhs)) - rhs = CInt64_Neg(rhs); - CInt64_DivMod(&lhs, &rhs, 0, &result); - return CInt64_Neg(result); - } else { - if (CInt64_IsNegative(&rhs)) - rhs = CInt64_Neg(rhs); - CInt64_DivMod(&lhs, &rhs, 0, &result); - return result; - } -} - -CInt64 CInt64_ModU(CInt64 lhs, CInt64 rhs) { - CInt64 result; - CInt64_DivMod(&lhs, &rhs, 0, &result); - return result; -} - -CInt64 CInt64_Shl(CInt64 lhs, CInt64 rhs) { - int counter; - unsigned long a; - unsigned long b; - - if (rhs.a == 0 && rhs.b < 64) { - a = lhs.a; - b = lhs.b; - for (counter = rhs.b; counter != 0; --counter) { - a <<= 1; - if (b & 0x80000000) - a |= 1; - b <<= 1; - } - lhs.a = a; - lhs.b = b; - } else { - lhs.a = 0; - lhs.b = 0; - } - return lhs; -} - -CInt64 CInt64_Shr(CInt64 lhs, CInt64 rhs) { - int counter; - long a; - unsigned long b; - - if (rhs.a == 0 && rhs.b < 64) { - a = lhs.a; - b = lhs.b; - for (counter = rhs.b; counter != 0; --counter) { - b >>= 1; - if (a & 1) - b |= 0x80000000; - a >>= 1; - } - lhs.a = a; - lhs.b = b; - } else { - if (lhs.a & 0x80000000) { - lhs.a = 0xFFFFFFFF; - lhs.b = 0xFFFFFFFF; - } else { - lhs.a = 0; - lhs.b = 0; - } - } - return lhs; -} - -CInt64 CInt64_ShrU(CInt64 lhs, CInt64 rhs) { - int counter; - unsigned long a; - unsigned long b; - - if (rhs.a == 0 && rhs.b < 64) { - a = lhs.a; - b = lhs.b; - for (counter = rhs.b; counter != 0; --counter) { - b >>= 1; - if (a & 1) - b |= 0x80000000; - a >>= 1; - } - lhs.a = a; - lhs.b = b; - } else { - lhs.a = 0; - lhs.b = 0; - } - return lhs; -} - -int CInt64_UnsignedCompare(const CInt64 *lhs, const CInt64 *rhs) { - if (lhs->a == rhs->a) { - if (lhs->b < rhs->b) - return -1; - else - return lhs->b > rhs->b; - } else { - return ((unsigned long) lhs->a < rhs->a) ? -1 : 1; - } -} - -int CInt64_SignedCompare(const CInt64 *lhs, const CInt64 *rhs) { - CInt64 lhs_; - CInt64 rhs_; - - lhs_ = CInt64_Xor(*lhs, cint64_min); - rhs_ = CInt64_Xor(*rhs, cint64_min); - return CInt64_UnsignedCompare(&lhs_, &rhs_); -} - -unsigned char CInt64_Less(CInt64 lhs, CInt64 rhs) { - return CInt64_SignedCompare(&lhs, &rhs) < 0; -} - -unsigned char CInt64_LessU(CInt64 lhs, CInt64 rhs) { - return CInt64_UnsignedCompare(&lhs, &rhs) < 0; -} - -unsigned char CInt64_Greater(CInt64 lhs, CInt64 rhs) { - return CInt64_SignedCompare(&lhs, &rhs) > 0; -} - -unsigned char CInt64_GreaterU(CInt64 lhs, CInt64 rhs) { - return CInt64_UnsignedCompare(&lhs, &rhs) > 0; -} - -unsigned char CInt64_LessEqual(CInt64 lhs, CInt64 rhs) { - return CInt64_SignedCompare(&lhs, &rhs) <= 0; -} - -unsigned char CInt64_LessEqualU(CInt64 lhs, CInt64 rhs) { - return CInt64_UnsignedCompare(&lhs, &rhs) <= 0; -} - -unsigned char CInt64_GreaterEqual(CInt64 lhs, CInt64 rhs) { - return CInt64_SignedCompare(&lhs, &rhs) >= 0; -} - -unsigned char CInt64_GreaterEqualU(CInt64 lhs, CInt64 rhs) { - return CInt64_UnsignedCompare(&lhs, &rhs) >= 0; -} - -unsigned char CInt64_Equal(CInt64 lhs, CInt64 rhs) { - return lhs.a == rhs.a && lhs.b == rhs.b; -} - -unsigned char CInt64_NotEqual(CInt64 lhs, CInt64 rhs) { - return lhs.a != rhs.a || lhs.b != rhs.b; -} - -unsigned char CInt64_IsInRange(CInt64 value, short len) { - CInt64 bound; - - if (value.a & 0x80000000) { - switch (len) { - case 1: - bound.b = 0xFFFFFF80; - bound.a = 0xFFFFFFFF; - break; - case 2: - bound.b = 0xFFFF8000; - bound.a = 0xFFFFFFFF; - break; - case 4: - bound.b = 0x80000000; - bound.a = 0xFFFFFFFF; - break; - case 8: - return 1; - default: - return 0; - } - return CInt64_GreaterEqual(value, bound); - } else { - switch (len) { - case 1: - bound.b = 0x7F; - bound.a = 0; - break; - case 2: - bound.b = 0x7FFF; - bound.a = 0; - break; - case 4: - bound.b = 0x7FFFFFFF; - bound.a = 0; - break; - case 8: - return 1; - default: - return 0; - } - return CInt64_LessEqual(value, bound); - } -} - -unsigned char CInt64_IsInURange(CInt64 value, short len) { - switch (len) { - case 1: - return value.a == 0 && (value.b & 0xFFFFFF00) == 0; - case 2: - return value.a == 0 && (value.b & 0xFFFF0000) == 0; - case 4: - return value.a == 0; - case 8: - return 1; - default: - return 0; - } -} - -CInt64 CInt64_And(CInt64 lhs, CInt64 rhs) { - lhs.a &= rhs.a; - lhs.b &= rhs.b; - return lhs; -} - -CInt64 CInt64_Xor(CInt64 lhs, CInt64 rhs) { - lhs.a ^= rhs.a; - lhs.b ^= rhs.b; - return lhs; -} - -CInt64 CInt64_Or(CInt64 lhs, CInt64 rhs) { - lhs.a |= rhs.a; - lhs.b |= rhs.b; - return lhs; -} - -void CInt64_ConvertInt32(CInt64 *i) { - CInt64_Extend32(i); -} - -void CInt64_ConvertUInt32(CInt64 *i) { - CInt64_SetULong(i, (unsigned long) i->b); -} - -void CInt64_ConvertInt16(CInt64 *i) { - i->b = (short) i->b; - CInt64_Extend32(i); -} - -void CInt64_ConvertUInt16(CInt64 *i) { - CInt64_SetULong(i, (unsigned short) i->b); -} - -void CInt64_ConvertInt8(CInt64 *i) { - i->b = (char) i->b; - CInt64_Extend32(i); -} - -void CInt64_ConvertUInt8(CInt64 *i) { - CInt64_SetULong(i, (unsigned char) i->b); -} - -void CInt64_ConvertUFromLongDouble(CInt64 *pResult, double value) { - union { float f; unsigned long l; } cvt; - unsigned long a, b; - float threshold; - int bits; - - if (value <= 0.0) { - pResult->a = 0; - pResult->b = 0; - return; - } - - cvt.l = 0x5F800000; - if (value >= cvt.f) { - pResult->a = 0xFFFFFFFF; - pResult->b = 0xFFFFFFFF; - return; - } - - a = b = 0; - for (bits = 63; bits >= 0; bits--) { - a <<= 1; - if (b & 0x80000000) - a |= 1; - b <<= 1; - - if ((short) bits == 0) { - threshold = 1.0f; - } else { - cvt.l = (((short) bits + 127) & 255) << 23; - threshold = cvt.f; - } - - if (threshold <= value) { - b |= 1; - value -= threshold; - } - } - - pResult->a = a; - pResult->b = b; -} - -void CInt64_ConvertFromLongDouble(CInt64 *pResult, double value) { - if (value < 0.0) { - CInt64_ConvertUFromLongDouble(pResult, -value); - *pResult = CInt64_Neg(*pResult); - } else { - CInt64_ConvertUFromLongDouble(pResult, value); - } -} - -double CInt64_ConvertUToLongDouble(const CInt64 *value) { - unsigned char bad; - unsigned long work; - int counter; - double result; - - bad = (value->a == 0) && (value->b == 0); - if (bad) { - return 0.0; - } else { - result = 0.0; - - work = value->a; - if (work != 0) { - for (counter = 0; counter < 32; counter++) { - result += result; - if (work & 0x80000000) - result += 1.0; - work <<= 1; - } - } - - counter = 0; - work = value->b; - for (; counter < 32; counter++) { - result += result; - if (work & 0x80000000) - result += 1.0; - work <<= 1; - } - - return result; - } -} - -double CInt64_ConvertToLongDouble(const CInt64 *value) { - CInt64 tmp; - if (value->a & 0x80000000) { - tmp = CInt64_Neg(*value); - return -CInt64_ConvertUToLongDouble(&tmp); - } else { - return CInt64_ConvertUToLongDouble(value); - } -} - -char *CInt64_ScanOctString(CInt64 *pResult, char *str, unsigned char *pFail) { - int ch; - CInt64 tmp; - unsigned long a; - unsigned long b; - - *pFail = 0; - pResult->a = pResult->b = 0; - - while ((ch = *str) >= '0' && *str <= '7') { - a = pResult->a; - b = pResult->b; - if (a & 0xE0000000) - *pFail = 1; - - SHIFT_LEFT_ONE(a, b); - SHIFT_LEFT_ONE(a, b); - SHIFT_LEFT_ONE(a, b); - - pResult->a = a; - pResult->b = b; - - CInt64_SetLong(&tmp, ch - '0'); - *pResult = CInt64_Add(*pResult, tmp); - ++str; - } - - return str; -} - -char *CInt64_ScanDecString(CInt64 *pResult, char *str, unsigned char *pFail) { - int ch; - CInt64 tmp; - unsigned long a; - unsigned long b; - - *pFail = 0; - pResult->a = pResult->b = 0; - - while ((ch = *str) >= '0' && *str <= '9') { - a = pResult->a; - b = pResult->b; - if (a & 0xE0000000) - *pFail = 1; - - SHIFT_LEFT_ONE(a, b); - tmp.a = a; - tmp.b = b; - SHIFT_LEFT_ONE(a, b); - SHIFT_LEFT_ONE(a, b); - pResult->a = a; - pResult->b = b; - - if (CInt64_IsNegative(pResult)) { - *pResult = CInt64_Add(*pResult, tmp); - if (!CInt64_IsNegative(pResult)) - *pFail = 1; - } else { - *pResult = CInt64_Add(*pResult, tmp); - } - - CInt64_SetLong(&tmp, ch - '0'); - if (CInt64_IsNegative(pResult)) { - *pResult = CInt64_Add(*pResult, tmp); - if (!CInt64_IsNegative(pResult)) - *pFail = 1; - } else { - *pResult = CInt64_Add(*pResult, tmp); - } - - ++str; - } - - return str; -} - -char *CInt64_ScanHexString(CInt64 *pResult, char *str, unsigned char *pFail) { - /* NOT MATCHING */ - int digit; - CInt64 tmp; - unsigned long a; - unsigned long b; - - *pFail = 0; - pResult->a = pResult->b = 0; - - for (;;) { - if ((digit = str[0]) >= '0' && digit <= '9') - digit = digit - '0'; - else if (digit >= 'A' && digit <= 'F') - digit = digit - 'A' + 10; - else if (digit >= 'a' && digit <= 'f') - digit = digit - 'a' + 10; - else - break; - - a = pResult->a; - b = pResult->b; - ++str; - - if (a & 0xF0000000) - *pFail = 1; - - SHIFT_LEFT_ONE(a, b); - SHIFT_LEFT_ONE(a, b); - SHIFT_LEFT_ONE(a, b); - SHIFT_LEFT_ONE(a, b); - - pResult->a = a; - pResult->b = b; - - CInt64_SetLong(&tmp, (char) digit); - *pResult = CInt64_Add(*pResult, tmp); - } - - return str; -} - -char *CInt64_ScanBinString(CInt64 *pResult, char *str, unsigned char *pFail) { - char digit; - unsigned long a; - unsigned long b; - - *pFail = 0; - pResult->a = pResult->b = 0; - - for (;;) { - if (*str == '0') - digit = 0; - else if (*str == '1') - digit = 1; - else - break; - - a = pResult->a; - b = pResult->b; - ++str; - - if (a & 0x80000000) - *pFail = 1; - - SHIFT_LEFT_ONE(a, b); - - pResult->a = a; - pResult->b = b; - - if (digit == 1) - *pResult = CInt64_Add(*pResult, cint64_one); - } - - return str; -} - -char *CInt64_ScanAsmNumber(CInt64 *pResult, char *str, unsigned char *pFail) { - unsigned char isMaybeBin; - unsigned char isOct; - unsigned char isMaybeDec; - unsigned char isBin; - char *p; - - isMaybeBin = 1; - isOct = *str == '0'; - isMaybeDec = 1; - isBin = 0; - p = str; - - for (;;) { - if (*p == 0) - break; - - if (strchr("01", p[0])) { - if (isBin) - isMaybeBin = 0; - } else if (strchr("bB", p[0])) { - isBin = 1; - isMaybeDec = 0; - isOct = 0; - } else if (strchr("234567", p[0])) { - isMaybeBin = 0; - } else if (strchr("89", p[0])) { - isOct = 0; - isMaybeBin = 0; - } else if (strchr("acdefACEDF", p[0])) { - isMaybeDec = 0; - isMaybeBin = 0; - } else { - break; - } - - ++p; - } - - if (isMaybeBin && isBin) { - return CInt64_ScanBinString(pResult, str, pFail) + 1; - } else if (p[0] == 'h' || p[0] == 'H') { - return CInt64_ScanHexString(pResult, str, pFail) + 1; - } else if (isOct) { - return CInt64_ScanOctString(pResult, str, pFail); - } else if (isMaybeDec) { - return CInt64_ScanDecString(pResult, str, pFail); - } else { - *pFail = 1; - return p; - } -} - -int CInt64_PrintDec(char *output, CInt64 value) { - int length; - CInt64 rem; - CInt64 divisor; - char buf[40]; - char *bufp; - - length = 0; - if (CInt64_IsNegative(&value)) { - value = CInt64_Neg(value); - *output = '-'; - length++; - output++; - } - - if (!CInt64_IsZero(&value)) { - divisor.b = 10; - divisor.a = 0; - - bufp = buf; - for (;;) { - rem = CInt64_ModU(value, divisor); - *(bufp++) = rem.b + '0'; - value = CInt64_DivU(value, divisor); - if (CInt64_IsZero(&value) != 0) - break; - } - - while (--bufp >= buf) { - *(output++) = *bufp; - length++; - } - } else { - *(output++) = '0'; - length++; - } - - *output = 0; - return length; -} - -int CInt64_PrintHex(char *output, CInt64 value) { - int length; - CInt64 rem; - CInt64 shift; - CInt64 mask; - char buf[32]; - char *bufp; - - length = 0; - if (!CInt64_IsZero(&value)) { - shift.b = 4; - shift.a = 0; - mask.b = 0xF; - mask.a = 0; - - bufp = buf; - for (;;) { - rem = CInt64_And(value, mask); - if ((long) rem.b >= 10) - *(bufp++) = rem.b + 'A'; - else - *(bufp++) = rem.b + '0'; - value = CInt64_ShrU(value, shift); - if (CInt64_IsZero(&value) != 0) - break; - } - - while (--bufp >= buf) { - *(output++) = *bufp; - length++; - } - } else { - *(output++) = '0'; - length++; - } - - *output = 0; - return length; -} - -int CInt64_PrintBin(char *output, CInt64 value) { - int length; - CInt64 rem; - char buf[64]; - char *bufp; - - length = 0; - if (!CInt64_IsZero(&value)) { - bufp = buf; - for (;;) { - rem = CInt64_And(value, cint64_one); - if (CInt64_Equal(rem, cint64_one)) - *(bufp++) = '1'; - else - *(bufp++) = '0'; - value = CInt64_ShrU(value, cint64_one); - if (CInt64_IsZero(&value) != 0) - break; - } - - while (--bufp >= buf) { - *(output++) = *bufp; - length++; - } - } else { - *(output++) = '0'; - length++; - } - - *output = 0; - return length; -} |