zsub.c - libzahl - big integer library | |
git clone git://git.suckless.org/libzahl | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
zsub.c (1941B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include "internals.h" | |
3 | |
4 | |
5 static inline void | |
6 zsub_impl(z_t a, z_t b, size_t n) | |
7 { | |
8 zahl_char_t carry = 0, tcarry; | |
9 size_t i; | |
10 | |
11 for (i = 0; i < n; i++) { | |
12 tcarry = carry ? (a->chars[i] <= b->chars[i]) : (a->char… | |
13 a->chars[i] -= b->chars[i]; | |
14 a->chars[i] -= carry; | |
15 carry = tcarry; | |
16 } | |
17 | |
18 if (carry) { | |
19 while (!a->chars[i]) | |
20 a->chars[i++] = ZAHL_CHAR_MAX; | |
21 if (a->chars[i] == 1) | |
22 a->used--; | |
23 else | |
24 a->chars[i] -= 1; | |
25 } | |
26 } | |
27 | |
28 static inline void | |
29 libzahl_zsub_unsigned(z_t a, z_t b, z_t c) | |
30 { | |
31 int magcmp; | |
32 size_t n; | |
33 | |
34 if (unlikely(zzero(b))) { | |
35 zabs(a, c); | |
36 zneg(a, a); | |
37 return; | |
38 } else if (unlikely(zzero(c))) { | |
39 zabs(a, b); | |
40 return; | |
41 } | |
42 | |
43 magcmp = zcmpmag(b, c); | |
44 if (unlikely(magcmp <= 0)) { | |
45 if (unlikely(magcmp == 0)) { | |
46 SET_SIGNUM(a, 0); | |
47 return; | |
48 } | |
49 n = b->used; | |
50 if (a == b) { | |
51 zset(libzahl_tmp_sub, b); | |
52 SET(a, c); | |
53 zsub_impl(a, libzahl_tmp_sub, n); | |
54 } else { | |
55 SET(a, c); | |
56 zsub_impl(a, b, n); | |
57 } | |
58 } else { | |
59 n = c->used; | |
60 if (unlikely(a == c)) { | |
61 zset(libzahl_tmp_sub, c); | |
62 SET(a, b); | |
63 zsub_impl(a, libzahl_tmp_sub, n); | |
64 } else { | |
65 SET(a, b); | |
66 zsub_impl(a, c, n); | |
67 } | |
68 } | |
69 | |
70 SET_SIGNUM(a, magcmp); | |
71 } | |
72 | |
73 void | |
74 zsub_unsigned(z_t a, z_t b, z_t c) | |
75 { | |
76 libzahl_zsub_unsigned(a, b, c); | |
77 } | |
78 | |
79 void | |
80 zsub_nonnegative_assign(z_t a, z_t b) | |
81 { | |
82 if (unlikely(zzero(b))) | |
83 zabs(a, a); | |
84 else if (unlikely(!zcmpmag(a, b))) | |
85 SET_SIGNUM(a, 0); | |
86 else | |
87 zsub_impl(a, b, b->used); | |
88 } | |
89 | |
90 void | |
91 zsub_positive_assign(z_t a, z_t b) | |
92 { | |
93 zsub_impl(a, b, b->used); | |
94 } | |
95 | |
96 void | |
97 zsub(z_t a, z_t b, z_t c) | |
98 { | |
99 if (unlikely(zzero(b))) { | |
100 zneg(a, c); | |
101 } else if (unlikely(zzero(c))) { | |
102 SET(a, b); | |
103 } else if (unlikely(znegative(b))) { | |
104 if (znegative(c)) { | |
105 libzahl_zsub_unsigned(a, c, b); | |
106 } else { | |
107 zadd_unsigned(a, b, c); | |
108 SET_SIGNUM(a, -zsignum(a)); | |
109 } | |
110 } else if (znegative(c)) { | |
111 zadd_unsigned(a, b, c); | |
112 } else { | |
113 libzahl_zsub_unsigned(a, b, c); | |
114 } | |
115 } |