summaryrefslogtreecommitdiff
path: root/CInt64.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2022-10-07 20:02:27 +0100
committerAsh Wolf <ninji@wuffs.org>2022-10-07 20:02:27 +0100
commit97f6a2438df1eaeb4128ce36f29346ea38a3db4a (patch)
tree78260f8f0f2b84fc70fadb1e50e7fc104390eee4 /CInt64.c
downloadMWCC-97f6a2438df1eaeb4128ce36f29346ea38a3db4a.tar.gz
MWCC-97f6a2438df1eaeb4128ce36f29346ea38a3db4a.zip
first very unfinished commit lol
Diffstat (limited to '')
-rw-r--r--CInt64.c893
1 files changed, 893 insertions, 0 deletions
diff --git a/CInt64.c b/CInt64.c
new file mode 100644
index 0000000..9b793bd
--- /dev/null
+++ b/CInt64.c
@@ -0,0 +1,893 @@
+#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;
+}