Statistics
| Branch: | Revision:

root / int128.h @ 4115852b

History | View | Annotate | Download (1.9 kB)

1
#ifndef INT128_H
2
#define INT128_H
3

    
4
typedef struct Int128 Int128;
5

    
6
struct Int128 {
7
    uint64_t lo;
8
    int64_t hi;
9
};
10

    
11
static inline Int128 int128_make64(uint64_t a)
12
{
13
    return (Int128) { a, 0 };
14
}
15

    
16
static inline uint64_t int128_get64(Int128 a)
17
{
18
    assert(!a.hi);
19
    return a.lo;
20
}
21

    
22
static inline Int128 int128_zero(void)
23
{
24
    return int128_make64(0);
25
}
26

    
27
static inline Int128 int128_one(void)
28
{
29
    return int128_make64(1);
30
}
31

    
32
static inline Int128 int128_2_64(void)
33
{
34
    return (Int128) { 0, 1 };
35
}
36

    
37
static inline Int128 int128_add(Int128 a, Int128 b)
38
{
39
    Int128 r = { a.lo + b.lo, a.hi + b.hi };
40
    r.hi += (r.lo < a.lo) || (r.lo < b.lo);
41
    return r;
42
}
43

    
44
static inline Int128 int128_neg(Int128 a)
45
{
46
    a.lo = ~a.lo;
47
    a.hi = ~a.hi;
48
    return int128_add(a, int128_one());
49
}
50

    
51
static inline Int128 int128_sub(Int128 a, Int128 b)
52
{
53
    return int128_add(a, int128_neg(b));
54
}
55

    
56
static inline bool int128_nonneg(Int128 a)
57
{
58
    return a.hi >= 0;
59
}
60

    
61
static inline bool int128_eq(Int128 a, Int128 b)
62
{
63
    return a.lo == b.lo && a.hi == b.hi;
64
}
65

    
66
static inline bool int128_ne(Int128 a, Int128 b)
67
{
68
    return !int128_eq(a, b);
69
}
70

    
71
static inline bool int128_ge(Int128 a, Int128 b)
72
{
73
    return int128_nonneg(int128_sub(a, b));
74
}
75

    
76
static inline bool int128_lt(Int128 a, Int128 b)
77
{
78
    return !int128_ge(a, b);
79
}
80

    
81
static inline bool int128_le(Int128 a, Int128 b)
82
{
83
    return int128_ge(b, a);
84
}
85

    
86
static inline bool int128_gt(Int128 a, Int128 b)
87
{
88
    return !int128_le(a, b);
89
}
90

    
91
static inline bool int128_nz(Int128 a)
92
{
93
    return a.lo || a.hi;
94
}
95

    
96
static inline Int128 int128_min(Int128 a, Int128 b)
97
{
98
    return int128_le(a, b) ? a : b;
99
}
100

    
101
static inline Int128 int128_max(Int128 a, Int128 b)
102
{
103
    return int128_ge(a, b) ? a : b;
104
}
105

    
106
static inline void int128_addto(Int128 *a, Int128 b)
107
{
108
    *a = int128_add(*a, b);
109
}
110

    
111
static inline void int128_subfrom(Int128 *a, Int128 b)
112
{
113
    *a = int128_sub(*a, b);
114
}
115

    
116
#endif