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