You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

85 lines
2.3 KiB

/* -*- 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;
}