#include "nibble.h" #include bcd bcd_zeros() { bcd bcd; memset(bcd.internal, 0, sizeof(bcd.internal)); return bcd; } #define bcd_from_n(X) {\ int i;\ bcd res = bcd_zeros();\ for (i = 9; i >= 0; --i) {\ if (!X) break;\ res.internal[i] = (X % 10);\ X /= 10;\ if (!X) break;\ res.internal[i] += (X % 10) << 4;\ X /= 10;\ }\ return res;\ } bcd bcd_from_8(uint8_t x) { bcd_from_n(x); } bcd bcd_from_16(uint16_t x) { bcd_from_n(x); } bcd bcd_from_32(uint32_t x) { bcd_from_n(x); } bcd bcd_from_64(uint64_t x) { bcd_from_n(x); } uint8_t bcd_digits(bcd x) { int i; for (i = 0; i < 20; i+=2) { if (x.internal[i/2] != 0) { if (!(x.internal[i/2]&0xf0)) i++; break; } } return 20-i; } uint64_t bcd_to_64(bcd x) { int i; uint64_t res = 0; for (i = 0; i < 10; ++i) { res *= 100; res += ((x.internal[i] & 0xf0) >> 4) * 10; res += (x.internal[i] & 0xf); } return res; } char* bcd_to_string(bcd x) { int i = 0; uint8_t n = bcd_digits(x); int to = 10-(n+1)/2; char* res = malloc(n+1); for (i = 0; i < n; i+=2, to++) { res[i] = ((x.internal[to] & 0xf0) >> 4) + '0'; res[i+1] = (x.internal[to] & 0xf) + '0'; } res[n] = '\0'; return res; }