// This code was meant only for me so there isn't many comments // Range 1 to 20 inclusive int ucount_digits(u64 val) { int count=1; if (val >= 10000000000000000ULL) { val /= 10000000000000000ULL; count += 16; } else { if (val >= 100000000ULL) { val /= 100000000ULL; count += 8; } if (val >= 10000ULL) { val /= 10000ULL; count += 4; } } if (val >= 100ULL) { val /= 100ULL; count += 2; } if (val >= 10ULL) { count++; } return count; } // Range 1 to 20 inclusive int scount_digits(s64 val) { if (val < 0) { return ucount_digits(-val) + 1; } else { return ucount_digits(val); } } int uitoa(u64 val, char *buf) { if (val < 10) { buf[0] = '0' + val; return 1; } // very common int charCount = ucount_digits(val); int pos = charCount; while (pos > 0) { buf[--pos] = '0' + val % 10; val /= 10; } return charCount; } int sitoa(s64 val_, char *buf) { u64 val=val_; if (val >= 0 && val < 10) { buf[0] = '0' + val; return 1; } // very common char isNeg = val_ < 0; if (isNeg) { val=-val; *buf++ = '-'; } int charCount = ucount_digits(val); int pos = charCount; while (pos > 0) { buf[--pos] = '0' + val % 10; val /= 10; } return charCount + isNeg; } // Table version static const u8 ascii0to99[] = {48, 48, 48, 49, 48, 50, 48, 51, 48, 52, 48, 53, 48, 54, 48, 55, 48, 56, 48, 57, 49, 48, 49, 49, 49, 50, 49, 51, 49, 52, 49, 53, 49, 54, 49, 55, 49, 56, 49, 57, 50, 48, 50, 49, 50, 50, 50, 51, 50, 52, 50, 53, 50, 54, 50, 55, 50, 56, 50, 57, 51, 48, 51, 49, 51, 50, 51, 51, 51, 52, 51, 53, 51, 54, 51, 55, 51, 56, 51, 57, 52, 48, 52, 49, 52, 50, 52, 51, 52, 52, 52, 53, 52, 54, 52, 55, 52, 56, 52, 57, 53, 48, 53, 49, 53, 50, 53, 51, 53, 52, 53, 53, 53, 54, 53, 55, 53, 56, 53, 57, 54, 48, 54, 49, 54, 50, 54, 51, 54, 52, 54, 53, 54, 54, 54, 55, 54, 56, 54, 57, 55, 48, 55, 49, 55, 50, 55, 51, 55, 52, 55, 53, 55, 54, 55, 55, 55, 56, 55, 57, 56, 48, 56, 49, 56, 50, 56, 51, 56, 52, 56, 53, 56, 54, 56, 55, 56, 56, 56, 57, 57, 48, 57, 49, 57, 50, 57, 51, 57, 52, 57, 53, 57, 54, 57, 55, 57, 56, 57, 57}; static inline int ucount_digits_table(u64 num) { static const int base[] = { 1, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 19 }; static const unsigned long long compare[] = { -1ULL, -1ULL, 10ULL, 100ULL, 100ULL, 1000ULL, -1ULL, 10000ULL, 100000ULL, 100000ULL, 1000000ULL, -1ULL, 10000000ULL, 100000000ULL, 1000000000ULL, 1000000000ULL, -1ULL, 10000000000ULL, 100000000000ULL , -1ULL , 1000000000000ULL, -1ULL, 10000000000000ULL, 100000000000000ULL, -1ULL, 1000000000000000ULL, -1ULL, 10000000000000000ULL, 100000000000000000ULL, -1ULL, 1000000000000000000ULL, -1ULL, 10000000000000000000ULL }; u64 lz_result = num == 0 ? 64 : __builtin_clzll(num); // Compiler replaces this with lzcnt u64 val = (64 - lz_result)>>1; return base[val] + (num >= compare[val]); } static inline int scount_digits_table(s64 val) { if (val < 0) { return ucount_digits_table(-val) + 1; } else { return ucount_digits_table(val); } } int uitoa_table(u64 val, char*buf) { if (val < 10) { buf[0] = '0' + val; return 1; } // very common int charCount = ucount_digits_table((u64)val); int pos = charCount; while (pos > 1) { u64 nextVal = val / 100; u64 low2 = val % 100; buf[--pos] = ascii0to99[low2*2+1]; buf[--pos] = ascii0to99[low2*2]; val = nextVal; } if (pos) { buf[--pos] = '0' + val; } return charCount; } int sitoa_table(s64 val_, char*buf) { u64 val=val_; if (val >= 0 && val < 10) { buf[0] = '0' + val; return 1; } // very common char isNeg = val_ < 0; if (isNeg) { val=-val; *buf++ = '-'; } int charCount = ucount_digits_table((u64)val); int pos = charCount; while (pos > 1) { u64 nextVal = val / 100; u64 low2 = val % 100; buf[--pos] = ascii0to99[low2*2+1]; buf[--pos] = ascii0to99[low2*2]; val = nextVal; } if (pos) { buf[--pos] = '0' + val; } return charCount + isNeg; }