62e3c17b |
1 | /* |
2 | * Handling of the int64 and uint64 types. Done in 32-bit integers, |
3 | * for (pre-C99) portability. Hopefully once C99 becomes widespread |
4 | * we can kiss this lot goodbye... |
5 | */ |
6 | |
7 | #include <assert.h> |
d92624dc |
8 | #include <string.h> |
62e3c17b |
9 | |
d92624dc |
10 | #include "int64.h" |
62e3c17b |
11 | |
32874aea |
12 | uint64 uint64_div10(uint64 x, int *remainder) |
13 | { |
62e3c17b |
14 | uint64 y; |
15 | int rem, r2; |
16 | y.hi = x.hi / 10; |
17 | y.lo = x.lo / 10; |
18 | rem = x.lo % 10; |
19 | /* |
20 | * Now we have to add in the remainder left over from x.hi. |
21 | */ |
22 | r2 = x.hi % 10; |
23 | y.lo += r2 * 2 * (0x80000000 / 10); |
24 | rem += r2 * 2 * (0x80000000 % 10); |
25 | y.lo += rem / 10; |
26 | rem %= 10; |
27 | |
28 | if (remainder) |
29 | *remainder = rem; |
30 | return y; |
31 | } |
32 | |
32874aea |
33 | void uint64_decimal(uint64 x, char *buffer) |
34 | { |
62e3c17b |
35 | char buf[20]; |
36 | int start = 20; |
37 | int d; |
38 | |
39 | while (x.hi || x.lo) { |
40 | x = uint64_div10(x, &d); |
41 | assert(start > 0); |
42 | buf[--start] = d + '0'; |
43 | } |
44 | |
32874aea |
45 | memcpy(buffer, buf + start, sizeof(buf) - start); |
46 | buffer[sizeof(buf) - start] = '\0'; |
62e3c17b |
47 | } |
48 | |
32874aea |
49 | uint64 uint64_make(unsigned long hi, unsigned long lo) |
50 | { |
62e3c17b |
51 | uint64 y; |
52 | y.hi = hi; |
53 | y.lo = lo; |
54 | return y; |
55 | } |
56 | |
32874aea |
57 | uint64 uint64_add(uint64 x, uint64 y) |
58 | { |
62e3c17b |
59 | x.lo += y.lo; |
60 | x.hi += y.hi + (x.lo < y.lo ? 1 : 0); |
61 | return x; |
62 | } |
63 | |
32874aea |
64 | uint64 uint64_add32(uint64 x, unsigned long y) |
65 | { |
62e3c17b |
66 | uint64 yy; |
67 | yy.hi = 0; |
68 | yy.lo = y; |
69 | return uint64_add(x, yy); |
70 | } |
d92624dc |
71 | |
72 | int uint64_compare(uint64 x, uint64 y) |
73 | { |
74 | if (x.hi != y.hi) |
75 | return x.hi < y.hi ? -1 : +1; |
76 | if (x.lo != y.lo) |
77 | return x.lo < y.lo ? -1 : +1; |
78 | return 0; |
79 | } |