Introduction
Introduction Statistics Contact Development Disclaimer Help
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 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.