Data Structures | |
| struct | qofint128 |
Functions | |
| gboolean | equal128 (qofint128 a, qofint128 b) |
| int | cmp128 (qofint128 a, qofint128 b) |
| qofint128 | shift128 (qofint128 x) |
| qofint128 | shiftleft128 (qofint128 x) |
| qofint128 | inc128 (qofint128 a) |
| qofint128 | add128 (qofint128 a, qofint128 b) |
| qofint128 | mult128 (gint64 a, gint64 b) |
| qofint128 | div128 (qofint128 n, gint64 d) |
| gint64 | rem128 (qofint128 n, gint64 d) |
| guint64 | gcf64 (guint64 num, guint64 denom) |
| qofint128 | lcm128 (guint64 a, guint64 b) |
Add a pair of 128-bit numbers, returning a 128-bit number
Definition at line 294 of file qofmath128.c.
00295 { 00296 qofint128 sum; 00297 if (a.isneg == b.isneg) 00298 { 00299 sum.isneg = a.isneg; 00300 sum.hi = a.hi + b.hi; 00301 sum.lo = a.lo + b.lo; 00302 if ((sum.lo < a.lo) || (sum.lo < b.lo)) 00303 { 00304 sum.hi ++; 00305 } 00306 sum.isbig = sum.hi || (sum.lo >> 63); 00307 return sum; 00308 } 00309 if ((b.hi > a.hi) || 00310 ((b.hi == a.hi) && (b.lo > a.lo))) 00311 { 00312 qofint128 tmp = a; 00313 a = b; 00314 b = tmp; 00315 } 00316 00317 sum.isneg = a.isneg; 00318 sum.hi = a.hi - b.hi; 00319 sum.lo = a.lo - b.lo; 00320 00321 if (sum.lo > a.lo) 00322 { 00323 sum.hi --; 00324 } 00325 00326 sum.isbig = sum.hi || (sum.lo >> 63); 00327 return sum; 00328 }
Return returns 1 if a>b, -1 if b>a, 0 if a == b
Definition at line 242 of file qofmath128.c.
00243 { 00244 if ((0 == a.isneg) && b.isneg) return 1; 00245 if (a.isneg && (0 == b.isneg)) return -1; 00246 if (0 == a.isneg) 00247 { 00248 if (a.hi > b.hi) return 1; 00249 if (a.hi < b.hi) return -1; 00250 if (a.lo > b.lo) return 1; 00251 if (a.lo < b.lo) return -1; 00252 return 0; 00253 } 00254 00255 if (a.hi > b.hi) return -1; 00256 if (a.hi < b.hi) return 1; 00257 if (a.lo > b.lo) return -1; 00258 if (a.lo < b.lo) return 1; 00259 return 0; 00260 }
Divide a signed 128-bit number by a signed 64-bit, returning a signed 128-bit number.
Definition at line 180 of file qofmath128.c.
00181 { 00182 qofint128 quotient; 00183 int i; 00184 guint64 remainder = 0; 00185 00186 quotient = n; 00187 if (0 > d) 00188 { 00189 d = -d; 00190 quotient.isneg = !quotient.isneg; 00191 } 00192 00193 /* Use grade-school long division algorithm */ 00194 for (i=0; i<128; i++) 00195 { 00196 guint64 sbit = HIBIT & quotient.hi; 00197 remainder <<= 1; 00198 if (sbit) remainder |= 1; 00199 quotient = shiftleft128 (quotient); 00200 if (remainder >= d) 00201 { 00202 remainder -= d; 00203 quotient.lo |= 1; 00204 } 00205 } 00206 00207 /* compute the carry situation */ 00208 quotient.isbig = (quotient.hi || (quotient.lo >> 63)); 00209 00210 return quotient; 00211 }
| guint64 gcf64 | ( | guint64 | num, | |
| guint64 | denom | |||
| ) | [inline] |
Return the greatest common factor of two 64-bit numbers
Definition at line 264 of file qofmath128.c.
00265 { 00266 guint64 t; 00267 00268 t = num % denom; 00269 num = denom; 00270 denom = t; 00271 00272 /* The strategy is to use Euclid's algorithm */ 00273 while (0 != denom) 00274 { 00275 t = num % denom; 00276 num = denom; 00277 denom = t; 00278 } 00279 /* num now holds the GCD (Greatest Common Divisor) */ 00280 return num; 00281 }
increment a 128-bit number by one
Definition at line 153 of file qofmath128.c.
00154 { 00155 if (0 == a.isneg) 00156 { 00157 a.lo ++; 00158 if (0 == a.lo) 00159 { 00160 a.hi ++; 00161 } 00162 } 00163 else 00164 { 00165 if (0 == a.lo) 00166 { 00167 a.hi --; 00168 } 00169 a.lo --; 00170 } 00171 00172 a.isbig = (a.hi != 0) || (a.lo >> 63); 00173 return a; 00174 }
| qofint128 lcm128 | ( | guint64 | a, | |
| guint64 | b | |||
| ) | [inline] |
Return the least common multiple of two 64-bit numbers.
Definition at line 285 of file qofmath128.c.
| qofint128 mult128 | ( | gint64 | a, | |
| gint64 | b | |||
| ) | [inline] |
Multiply a pair of signed 64-bit numbers, returning a signed 128-bit number.
Definition at line 41 of file qofmath128.c.
00042 { 00043 qofint128 prod; 00044 guint64 a0, a1; 00045 guint64 b0, b1; 00046 guint64 d, d0, d1; 00047 guint64 e, e0, e1; 00048 guint64 f, f0, f1; 00049 guint64 g, g0, g1; 00050 guint64 sum, carry, roll, pmax; 00051 00052 prod.isneg = 0; 00053 if (0>a) 00054 { 00055 prod.isneg = !prod.isneg; 00056 a = -a; 00057 } 00058 00059 if (0>b) 00060 { 00061 prod.isneg = !prod.isneg; 00062 b = -b; 00063 } 00064 00065 a1 = a >> 32; 00066 a0 = a - (a1<<32); 00067 00068 b1 = b >> 32; 00069 b0 = b - (b1<<32); 00070 00071 d = a0*b0; 00072 d1 = d >> 32; 00073 d0 = d - (d1<<32); 00074 00075 e = a0*b1; 00076 e1 = e >> 32; 00077 e0 = e - (e1<<32); 00078 00079 f = a1*b0; 00080 f1 = f >> 32; 00081 f0 = f - (f1<<32); 00082 00083 g = a1*b1; 00084 g1 = g >> 32; 00085 g0 = g - (g1<<32); 00086 00087 sum = d1+e0+f0; 00088 carry = 0; 00089 /* Can't say 1<<32 cause cpp will goof it up; 1ULL<<32 might work */ 00090 roll = 1<<30; 00091 roll <<= 2; 00092 00093 pmax = roll-1; 00094 while (pmax < sum) 00095 { 00096 sum -= roll; 00097 carry ++; 00098 } 00099 00100 prod.lo = d0 + (sum<<32); 00101 prod.hi = carry + e1 + f1 + g0 + (g1<<32); 00102 // prod.isbig = (prod.hi || (sum >> 31)); 00103 prod.isbig = prod.hi || (prod.lo >> 63); 00104 00105 return prod; 00106 }
| gint64 rem128 | ( | qofint128 | n, | |
| gint64 | d | |||
| ) | [inline] |
Return the remainder of a signed 128-bit number modulo a signed 64-bit. That is, return nd in 128-bit math. I beleive that ths algo is overflow-free, but should be audited some more ...
Definition at line 219 of file qofmath128.c.
00220 { 00221 qofint128 quotient = div128 (n,d); 00222 00223 qofint128 mu = mult128 (quotient.lo, d); 00224 00225 gint64 nn = 0x7fffffffffffffffULL & n.lo; 00226 gint64 rr = 0x7fffffffffffffffULL & mu.lo; 00227 return nn - rr; 00228 }
Shift right by one bit (i.e. divide by two)
Definition at line 110 of file qofmath128.c.
00111 { 00112 guint64 sbit = x.hi & 0x1; 00113 x.hi >>= 1; 00114 x.lo >>= 1; 00115 x.isbig = 0; 00116 if (sbit) 00117 { 00118 x.lo |= HIBIT; 00119 x.isbig = 1; 00120 return x; 00121 } 00122 if (x.hi) 00123 { 00124 x.isbig = 1; 00125 } 00126 return x; 00127 }
Shift leftt by one bit (i.e. multiply by two)
Definition at line 131 of file qofmath128.c.
00132 { 00133 guint64 sbit; 00134 sbit = x.lo & HIBIT; 00135 x.hi <<= 1; 00136 x.lo <<= 1; 00137 x.isbig = 0; 00138 if (sbit) 00139 { 00140 x.hi |= 1; 00141 x.isbig = 1; 00142 return x; 00143 } 00144 if (x.hi) 00145 { 00146 x.isbig = 1; 00147 } 00148 return x; 00149 }
1.5.2