Long integer divide */
| 229 | |
| 230 | /* Long integer divide */ |
| 231 | static inline npy_extint128_t |
| 232 | divmod_128_64(npy_extint128_t x, npy_int64 b, npy_int64 *mod) |
| 233 | { |
| 234 | npy_extint128_t remainder, pointer, result, divisor; |
| 235 | char overflow = 0; |
| 236 | |
| 237 | assert(b > 0); |
| 238 | |
| 239 | if (b <= 1 || x.hi == 0) { |
| 240 | result.sign = x.sign; |
| 241 | result.lo = x.lo / b; |
| 242 | result.hi = x.hi / b; |
| 243 | *mod = x.sign * (x.lo % b); |
| 244 | return result; |
| 245 | } |
| 246 | |
| 247 | /* Long division, not the most efficient choice */ |
| 248 | remainder = x; |
| 249 | remainder.sign = 1; |
| 250 | |
| 251 | divisor.sign = 1; |
| 252 | divisor.hi = 0; |
| 253 | divisor.lo = b; |
| 254 | |
| 255 | result.sign = 1; |
| 256 | result.lo = 0; |
| 257 | result.hi = 0; |
| 258 | |
| 259 | pointer.sign = 1; |
| 260 | pointer.lo = 1; |
| 261 | pointer.hi = 0; |
| 262 | |
| 263 | while ((divisor.hi & (((npy_uint64)1) << 63)) == 0 && |
| 264 | gt_128(remainder, divisor)) { |
| 265 | divisor = shl_128(divisor); |
| 266 | pointer = shl_128(pointer); |
| 267 | } |
| 268 | |
| 269 | while (pointer.lo || pointer.hi) { |
| 270 | if (!gt_128(divisor, remainder)) { |
| 271 | remainder = sub_128(remainder, divisor, &overflow); |
| 272 | result = add_128(result, pointer, &overflow); |
| 273 | } |
| 274 | divisor = shr_128(divisor); |
| 275 | pointer = shr_128(pointer); |
| 276 | } |
| 277 | |
| 278 | /* Fix signs and return; cannot overflow */ |
| 279 | result.sign = x.sign; |
| 280 | *mod = x.sign * remainder.lo; |
| 281 | |
| 282 | return result; |
| 283 | } |
| 284 | |
| 285 | |
| 286 | /* Divide and round down (positive divisor; no overflows) */ |