|
|
/* -*- coding: utf-8 -*-
* ---------------------------------------------------------------------- * Copyright © 2013, RedJack, LLC. * All rights reserved. * * Please see the COPYING file in this distribution for license details. * ---------------------------------------------------------------------- */
#include <string.h>
#include <stdio.h>
#include "libcork/core/types.h"
#include "libcork/core/u128.h"
/* From http://stackoverflow.com/questions/8023414/how-to-convert-a-128-bit-integer-to-a-decimal-ascii-string-in-c */
const char * cork_u128_to_decimal(char *dest, cork_u128 val) { uint32_t n[4]; char *s = dest; char *p = dest; unsigned int i;
/* This algorithm assumes that n[3] is the MSW. */ n[3] = cork_u128_be32(val, 0); n[2] = cork_u128_be32(val, 1); n[1] = cork_u128_be32(val, 2); n[0] = cork_u128_be32(val, 3);
memset(s, '0', CORK_U128_DECIMAL_LENGTH - 1); s[CORK_U128_DECIMAL_LENGTH - 1] = '\0';
for (i = 0; i < 128; i++) { unsigned int j; unsigned int carry;
carry = (n[3] >= 0x80000000); /* Shift n[] left, doubling it */ n[3] = ((n[3] << 1) & 0xFFFFFFFF) + (n[2] >= 0x80000000); n[2] = ((n[2] << 1) & 0xFFFFFFFF) + (n[1] >= 0x80000000); n[1] = ((n[1] << 1) & 0xFFFFFFFF) + (n[0] >= 0x80000000); n[0] = ((n[0] << 1) & 0xFFFFFFFF);
/* Add s[] to itself in decimal, doubling it */ for (j = CORK_U128_DECIMAL_LENGTH - 1; j-- > 0; ) { s[j] += s[j] - '0' + carry; carry = (s[j] > '9'); if (carry) { s[j] -= 10; } } }
while ((p[0] == '0') && (p < &s[CORK_U128_DECIMAL_LENGTH - 2])) { p++; }
return p; }
const char * cork_u128_to_hex(char *buf, cork_u128 val) { uint64_t hi = val._.be64.hi; uint64_t lo = val._.be64.lo; if (hi == 0) { snprintf(buf, CORK_U128_HEX_LENGTH, "%" PRIx64, lo); } else { snprintf(buf, CORK_U128_HEX_LENGTH, "%" PRIx64 "%016" PRIx64, hi, lo); } return buf; }
const char * cork_u128_to_padded_hex(char *buf, cork_u128 val) { uint64_t hi = val._.be64.hi; uint64_t lo = val._.be64.lo; snprintf(buf, CORK_U128_HEX_LENGTH, "%016" PRIx64 "%016" PRIx64, hi, lo); return buf; }
|