LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
longlong.h 文件参考
#include <stdint.h>
+ longlong.h 的引用(Include)关系图:
+ 此图展示该文件直接或间接的被哪些文件引用了:

浏览源代码.

结构体

struct  _udiv64_t
 

宏定义

#define _ADD_MARKER   0x40
 
#define _add_ssaaaa(sh, sl, ah, al, bh, bl)
 
#define _sub_ddmmss(sh, sl, ah, al, bh, bl)
 
#define _u128add(r, x, y)
 
#define _u128add64(r, x, _i64)
 
#define _u128cmp(x, y)   ((x)[1] < (y)[1] || ((x)[1] == (y)[1] && (x)[0] < (y)[0]))
 
#define _u128high(x)   (*((x) + 1))
 
#define _u128low(x)   (*(x))
 
#define _u128lshl(x, y, n)
 
#define _u128lshr(x, y, n)
 
#define _u128mul(r, x, y)   _umul64to128_((x), (y), (r), (((r) + 1)))
 
#define _u128sub(r, x, y)
 
#define _u128sub64(r, x, _i64)
 
#define _u192add(i192, j192)
 
#define _u192sub(i192, j192)
 
#define _U64_SHIFT_MASK   0x3F
 from https://libdivide.com/
 
#define _udiv32by32_q_preinv(q, n0, dinv)
 
#define _udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv)
 
#define _udiv_qrnnd_preinv(q, r, nh, nl, d, di)
 
#define clz_shl_u32(r, x, cnt)
 
#define clz_shl_u64(r, x, cnt)
 
#define ctz_shr_u32(r, x, cnt)
 
#define ctz_shr_u64(r, x, cnt)
 Copyright (C) 2026 HJimmyK(Jericho Knox)
 

类型定义

typedef struct _udiv64_t _udiv64_t
 
typedef uint64_t u128[2]
 
typedef uint64_t u192[3]
 

函数

static uint64_t _udiv128by64to64_ (uint64_t numhi, uint64_t numlo, uint64_t den, uint64_t *r)
 
static _udiv64_t _udiv64_gen (uint64_t d)
 
static _udiv64_t _udiv64_gen_internal_ (uint64_t d, int branchfree)
 
static uint64_t _udiv64by64_q_preinv (uint64_t numer, const _udiv64_t *denom)
 
static void _umul128to128_ (uint64_t a_high, uint64_t a_low, uint64_t b_high, uint64_t b_low, uint64_t rr[2])
 
static void _umul128to256_ (uint64_t a_high, uint64_t a_low, uint64_t b_high, uint64_t b_low, uint64_t rr[4])
 
static void _umul64to128_ (uint64_t a, uint64_t b, uint64_t *low, uint64_t *high)
 
static uint64_t _umul64to64hi_ (uint64_t a, uint64_t b)
 
static void _usqr128to256_ (uint64_t a_high, uint64_t a_low, uint64_t rr[4])
 

结构体说明

◆ _udiv64_t

struct _udiv64_t

在文件 longlong.h501 行定义.

+ _udiv64_t 的协作图:
成员变量
uint64_t magic
uint8_t more

宏定义说明

◆ _ADD_MARKER

#define _ADD_MARKER   0x40

在文件 longlong.h499 行定义.

◆ _add_ssaaaa

#define _add_ssaaaa (   sh,
  sl,
  ah,
  al,
  bh,
  bl 
)
值:
do { \
uint64_t _x_; \
_x_ = (al) + (bl); \
(sh) = (ah) + (bh) + (_x_ < (al)); \
(sl) = _x_; \
} while (0)
#define n

在文件 longlong.h425 行定义.

426 { \
427 uint64_t _x_; \
428 _x_ = (al) + (bl); \
429 (sh) = (ah) + (bh) + (_x_ < (al)); \
430 (sl) = _x_; \
431 } while (0)

◆ _sub_ddmmss

#define _sub_ddmmss (   sh,
  sl,
  ah,
  al,
  bh,
  bl 
)
值:
do { \
uint64_t _x_; \
_x_ = (al) - (bl); \
(sh) = (ah) - (bh) - ((al) < (bl)); \
(sl) = _x_; \
} while (0)

在文件 longlong.h433 行定义.

434 { \
435 uint64_t _x_; \
436 _x_ = (al) - (bl); \
437 (sh) = (ah) - (bh) - ((al) < (bl)); \
438 (sl) = _x_; \
439 } while (0)

◆ _u128add

#define _u128add (   r,
  x,
  y 
)
值:
do { \
(*(r)) = *(x) + *(y); \
(*((r) + 1)) = (*((x) + 1)) + (*((y) + 1)) + ((*(r)) < (*(y)) ? 1 : 0); \
} while (0)

在文件 longlong.h372 行定义.

373 { \
374 (*(r)) = *(x) + *(y); \
375 (*((r) + 1)) = (*((x) + 1)) + (*((y) + 1)) + ((*(r)) < (*(y)) ? 1 : 0); \
376 } while (0)

◆ _u128add64

#define _u128add64 (   r,
  x,
  _i64 
)
值:
do { \
(*(r)) = *(x) + (_i64); \
(*((r) + 1)) = (*((x) + 1)) + (((*(r)) < (_i64)) ? 1 : 0); \
} while (0)

在文件 longlong.h378 行定义.

379 { \
380 (*(r)) = *(x) + (_i64); \
381 (*((r) + 1)) = (*((x) + 1)) + (((*(r)) < (_i64)) ? 1 : 0); \
382 } while (0)

◆ _u128cmp

#define _u128cmp (   x,
  y 
)    ((x)[1] < (y)[1] || ((x)[1] == (y)[1] && (x)[0] < (y)[0]))

在文件 longlong.h392 行定义.

◆ _u128high

#define _u128high (   x)    (*((x) + 1))

在文件 longlong.h368 行定义.

◆ _u128low

#define _u128low (   x)    (*(x))

在文件 longlong.h370 行定义.

◆ _u128lshl

#define _u128lshl (   x,
  y,
  n 
)
值:
do { \
(*((x) + 1)) = ((*(y)) >> (64 - (n))) | ((*((y) + 1)) << (n)); \
(*(x)) = (*(y)) << (n); \
} while (0)

在文件 longlong.h356 行定义.

357 { \
358 (*((x) + 1)) = ((*(y)) >> (64 - (n))) | ((*((y) + 1)) << (n)); \
359 (*(x)) = (*(y)) << (n); \
360 } while (0)

◆ _u128lshr

#define _u128lshr (   x,
  y,
  n 
)
值:
do { \
(*(x)) = ((*(y)) >> (n)) | ((*((y) + 1)) << (64 - (n))); \
(*((x) + 1)) = (*((y) + 1)) >> (n); \
} while (0)

在文件 longlong.h362 行定义.

363 { \
364 (*(x)) = ((*(y)) >> (n)) | ((*((y) + 1)) << (64 - (n))); \
365 (*((x) + 1)) = (*((y) + 1)) >> (n); \
366 } while (0)

◆ _u128mul

#define _u128mul (   r,
  x,
  y 
)    _umul64to128_((x), (y), (r), (((r) + 1)))

在文件 longlong.h401 行定义.

◆ _u128sub

#define _u128sub (   r,
  x,
  y 
)
值:
do { \
uint64_t _c_ = (x)[0] < (y)[0]; \
(r)[0] = (x)[0] - (y)[0]; \
(r)[1] = (x)[1] - (y)[1] - _c_; \
} while (0)

在文件 longlong.h394 行定义.

395 { \
396 uint64_t _c_ = (x)[0] < (y)[0]; \
397 (r)[0] = (x)[0] - (y)[0]; \
398 (r)[1] = (x)[1] - (y)[1] - _c_; \
399 } while (0)

◆ _u128sub64

#define _u128sub64 (   r,
  x,
  _i64 
)
值:
do { \
uint64_t _c_ = (x)[0] < (_i64); \
(r)[0] = (x)[0] - (_i64); \
(r)[1] = (x)[1] - _c_; \
} while (0)

在文件 longlong.h384 行定义.

385 { \
386 uint64_t _c_ = (x)[0] < (_i64); \
387 (r)[0] = (x)[0] - (_i64); \
388 (r)[1] = (x)[1] - _c_; \
389 } while (0)

◆ _u192add

#define _u192add (   i192,
  j192 
)
值:
do { \
(i192)[0] += (j192)[0]; \
uint64_t _c_ = ((i192)[0] < (j192)[0]) ? 1 : 0; \
(i192)[1] += _c_; \
_c_ = ((i192)[1] < _c_) ? 1 : 0; \
(i192)[1] += (j192)[1]; \
_c_ += ((i192)[1] < (j192)[1]) ? 1 : 0; \
(i192)[2] += _c_ + (j192)[2]; \
} while (0)

在文件 longlong.h403 行定义.

404 { \
405 (i192)[0] += (j192)[0]; \
406 uint64_t _c_ = ((i192)[0] < (j192)[0]) ? 1 : 0; \
407 (i192)[1] += _c_; \
408 _c_ = ((i192)[1] < _c_) ? 1 : 0; \
409 (i192)[1] += (j192)[1]; \
410 _c_ += ((i192)[1] < (j192)[1]) ? 1 : 0; \
411 (i192)[2] += _c_ + (j192)[2]; \
412 } while (0)

◆ _u192sub

#define _u192sub (   i192,
  j192 
)
值:
do { \
uint64_t _b_ = ((i192)[0] < (j192)[0]) ? 1 : 0; \
(i192)[0] -= (j192)[0]; \
uint64_t _b1_ = ((i192)[1] < (j192)[1]) ? 1 : 0; \
(i192)[1] -= (j192)[1]; \
_b1_ += ((i192)[1] < _b_) ? 1 : 0; \
(i192)[1] -= _b_; \
(i192)[2] = (i192)[2] - ((j192)[2] + _b1_); \
} while (0)

在文件 longlong.h414 行定义.

415 { \
416 uint64_t _b_ = ((i192)[0] < (j192)[0]) ? 1 : 0; \
417 (i192)[0] -= (j192)[0]; \
418 uint64_t _b1_ = ((i192)[1] < (j192)[1]) ? 1 : 0; \
419 (i192)[1] -= (j192)[1]; \
420 _b1_ += ((i192)[1] < _b_) ? 1 : 0; \
421 (i192)[1] -= _b_; \
422 (i192)[2] = (i192)[2] - ((j192)[2] + _b1_); \
423 } while (0)

◆ _U64_SHIFT_MASK

#define _U64_SHIFT_MASK   0x3F

from https://libdivide.com/

在文件 longlong.h498 行定义.

◆ _udiv32by32_q_preinv

#define _udiv32by32_q_preinv (   q,
  n0,
  dinv 
)
值:
do { \
uint64_t _hi_, _lo_; \
(q) = _hi_; \
} while (0)

在文件 longlong.h487 行定义.

488 { \
489 uint64_t _hi_, _lo_; \
490 _umul64to128_((n0), (dinv), &_lo_, &_hi_); \
491 (q) = _hi_; \
492 } while (0)

◆ _udiv_qr_3by2

#define _udiv_qr_3by2 (   q,
  r1,
  r0,
  n2,
  n1,
  n0,
  d1,
  d0,
  dinv 
)
值:
do { \
_umul64to128_((n2), (dinv), &_q0_, &(q)); \
_add_ssaaaa((q), _q0_, (q), _q0_, (n2), (n1)); \
/* Compute the two most significant limbs of n - q'd */ \
(r1) = (n1) - (d1) * (q); \
_sub_ddmmss((r1), (r0), (r1), (n0), (d1), (d0)); \
_sub_ddmmss((r1), (r0), (r1), (r0), _t1_, _t0_); \
(q)++; \
/* Conditionally adjust q and the remainders */ \
_mask_ = -(uint64_t)((r1) >= _q0_); \
(q) += _mask_; \
_add_ssaaaa((r1), (r0), (r1), (r0), _mask_ & (d1), _mask_ & (d0)); \
if ((r1) >= (d1)) { \
if ((r1) > (d1) || (r0) >= (d0)) { \
(q)++; \
_sub_ddmmss((r1), (r0), (r1), (r0), (d1), (d0)); \
} \
} \
} while (0)
uint64_t mp_limb_t
Definition lmmp.h:113
#define r1
#define r0

在文件 longlong.h462 行定义.

463 { \
465 _umul64to128_((n2), (dinv), &_q0_, &(q)); \
466 _add_ssaaaa((q), _q0_, (q), _q0_, (n2), (n1)); \
467 /* Compute the two most significant limbs of n - q'd */ \
468 (r1) = (n1) - (d1) * (q); \
469 _sub_ddmmss((r1), (r0), (r1), (n0), (d1), (d0)); \
470 _umul64to128_((d0), (q), &_t0_, &_t1_); \
471 _sub_ddmmss((r1), (r0), (r1), (r0), _t1_, _t0_); \
472 (q)++; \
473 /* Conditionally adjust q and the remainders */ \
474 _mask_ = -(uint64_t)((r1) >= _q0_); \
475 (q) += _mask_; \
476 _add_ssaaaa((r1), (r0), (r1), (r0), _mask_ & (d1), _mask_ & (d0)); \
477 if ((r1) >= (d1)) { \
478 if ((r1) > (d1) || (r0) >= (d0)) { \
479 (q)++; \
480 _sub_ddmmss((r1), (r0), (r1), (r0), (d1), (d0)); \
481 } \
482 } \
483 } while (0)

◆ _udiv_qrnnd_preinv

#define _udiv_qrnnd_preinv (   q,
  r,
  nh,
  nl,
  d,
  di 
)
值:
do { \
uint64_t _qh_, _ql_, _r_, _mask_; \
_add_ssaaaa(_qh_, _ql_, _qh_, _ql_, (nh) + 1, (nl)); \
_r_ = (nl) - _qh_ * (d); \
_mask_ = -(mp_limb_t)(_r_ > _ql_); \
_qh_ += _mask_; \
_r_ += _mask_ & (d); \
if (_r_ >= (d)) { \
_r_ -= (d); \
_qh_++; \
} \
(r) = _r_; \
(q) = _qh_; \
} while (0)

在文件 longlong.h443 行定义.

444 { \
445 uint64_t _qh_, _ql_, _r_, _mask_; \
446 _umul64to128_((nh), (di), &_ql_, &_qh_); \
447 _add_ssaaaa(_qh_, _ql_, _qh_, _ql_, (nh) + 1, (nl)); \
448 _r_ = (nl) - _qh_ * (d); \
449 _mask_ = -(mp_limb_t)(_r_ > _ql_); \
450 _qh_ += _mask_; \
451 _r_ += _mask_ & (d); \
452 if (_r_ >= (d)) { \
453 _r_ -= (d); \
454 _qh_++; \
455 } \
456 (r) = _r_; \
457 (q) = _qh_; \
458 } while (0)

◆ clz_shl_u32

#define clz_shl_u32 (   r,
  x,
  cnt 
)
值:
do { \
uint32_t _x_ = (x); \
int _c_ = 0; \
while ((_x_ & 0x80000000U) == 0) { \
_c_++; \
_x_ <<= 1; \
} \
(cnt) = _c_; \
(r) = _x_; \
} while (0)

在文件 longlong.h161 行定义.

162 { \
163 uint32_t _x_ = (x); \
164 int _c_ = 0; \
165 while ((_x_ & 0x80000000U) == 0) { \
166 _c_++; \
167 _x_ <<= 1; \
168 } \
169 (cnt) = _c_; \
170 (r) = _x_; \
171 } while (0)

◆ clz_shl_u64

#define clz_shl_u64 (   r,
  x,
  cnt 
)
值:
do { \
uint64_t _x_ = (x); \
int _c_ = 0; \
while ((_x_ & 0x8000000000000000ULL) == 0) { \
_c_++; \
_x_ <<= 1; \
} \
(cnt) = _c_; \
(r) = _x_; \
} while (0)

在文件 longlong.h88 行定义.

89 { \
90 uint64_t _x_ = (x); \
91 int _c_ = 0; \
92 while ((_x_ & 0x8000000000000000ULL) == 0) { \
93 _c_++; \
94 _x_ <<= 1; \
95 } \
96 (cnt) = _c_; \
97 (r) = _x_; \
98 } while (0)

◆ ctz_shr_u32

#define ctz_shr_u32 (   r,
  x,
  cnt 
)
值:
do { \
uint32_t _x_ = (x); \
int _i_ = 0; \
while ((_x_ & 1U) == 0) { \
_i_++; \
_x_ >>= 1; \
} \
cnt = _i_; \
(r) = _x_; \
} while (0)

在文件 longlong.h147 行定义.

148 { \
149 uint32_t _x_ = (x); \
150 int _i_ = 0; \
151 while ((_x_ & 1U) == 0) { \
152 _i_++; \
153 _x_ >>= 1; \
154 } \
155 cnt = _i_; \
156 (r) = _x_; \
157 } while (0)

◆ ctz_shr_u64

#define ctz_shr_u64 (   r,
  x,
  cnt 
)
值:
do { \
uint64_t _x_ = (x); \
int _i_ = 0; \
while ((_x_ & 1) == 0) { \
_i_++; \
_x_ >>= 1; \
} \
cnt = _i_; \
(r) = _x_; \
} while (0)

Copyright (C) 2026 HJimmyK(Jericho Knox)

This file is part of LAMMP.

LAMMP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This program is distributed WITHOUT ANY WARRANTY.

See https://www.gnu.org/licenses/.

在文件 longlong.h74 行定义.

75 { \
76 uint64_t _x_ = (x); \
77 int _i_ = 0; \
78 while ((_x_ & 1) == 0) { \
79 _i_++; \
80 _x_ >>= 1; \
81 } \
82 cnt = _i_; \
83 (r) = _x_; \
84 } while (0)

类型定义说明

◆ _udiv64_t

◆ u128

typedef uint64_t u128[2]

在文件 longlong.h353 行定义.

◆ u192

typedef uint64_t u192[3]

在文件 longlong.h354 行定义.

函数说明

◆ _udiv128by64to64_()

static uint64_t _udiv128by64to64_ ( uint64_t  numhi,
uint64_t  numlo,
uint64_t  den,
uint64_t *  r 
)
inlinestatic

在文件 longlong.h273 行定义.

273 {
274#if (defined(__GNUC__) || defined(__clang__)) && defined(USE_ASM)
275 uint64_t result;
276 __asm__("div %[v]" : "=a"(result), "=d"(*r) : [v] "r"(den), "a"(numlo), "d"(numhi));
277 return result;
278#elif defined(__GNUC__)
280 uint64_t result = num / den;
281 *r = num % den;
282 return result;
283#elif defined(_MSC_VER) && (defined(_M_X64)) && (!defined(__clang__))
284 return _udiv128(numhi, numlo, den, r);
285#else
286 const uint64_t b = ((uint64_t)1 << 32);
287
288 uint32_t q1;
289 uint32_t q0;
290
291 uint64_t q;
292
293 int shift;
294
295 uint64_t den10 = den;
296 uint64_t num10 = numlo;
297
298 uint32_t den1;
299 uint32_t den0;
300 uint32_t num1;
301 uint32_t num0;
302
303 uint64_t rem;
304
305 uint64_t qhat;
306 uint64_t rhat;
307
308 uint64_t c1;
309 uint64_t c2;
310
311 if (numhi >= den) {
312 if (r)
313 *r = ~0ull;
314 return ~0ull;
315 }
316
318 numhi <<= shift;
319 numhi |= (numlo >> (-shift & 63)) & (uint64_t)(-(int64_t)shift >> 63);
320 numlo <<= shift;
321
322 num1 = (uint32_t)(numlo >> 32);
323 num0 = (uint32_t)(numlo & 0xFFFFFFFFu);
324 den1 = (uint32_t)(den >> 32);
325 den0 = (uint32_t)(den & 0xFFFFFFFFu);
326
327 qhat = numhi / den1;
328 rhat = numhi % den1;
329 c1 = qhat * den0;
330 c2 = rhat * b + num1;
331 if (c1 > c2)
332 qhat -= (c1 - c2 > den) ? 2 : 1;
333 q1 = (uint32_t)qhat;
334
335 rem = numhi * b + num1 - q1 * den;
336
337 qhat = rem / den1;
338 rhat = rem % den1;
339 c1 = qhat * den0;
340 c2 = rhat * b + num0;
341 if (c1 > c2)
342 qhat -= (c1 - c2 > den) ? 2 : 1;
343 q0 = (uint32_t)qhat;
344
345 q = ((uint64_t)q1 << 32) | q0;
346
347 if (r)
348 *r = num10 - q * den10;
349 return q;
350#endif
351}
#define clz_shl_u64(r, x, cnt)
Definition longlong.h:88
#define c1

引用了 c1 , 以及 clz_shl_u64.

被这些函数引用 _udiv64_gen_internal_().

+ 这是这个函数的调用关系图:

◆ _udiv64_gen()

static _udiv64_t _udiv64_gen ( uint64_t  d)
inlinestatic

在文件 longlong.h560 行定义.

560 {
562 _udiv64_t ret = {tmp.magic, (uint8_t)(tmp.more & _U64_SHIFT_MASK)};
563 return ret;
564}
#define _U64_SHIFT_MASK
from https://libdivide.com/
Definition longlong.h:498
static _udiv64_t _udiv64_gen_internal_(uint64_t d, int branchfree)
Definition longlong.h:507
uint64_t magic
Definition longlong.h:502
#define tmp

引用了 _U64_SHIFT_MASK, _udiv64_gen_internal_(), _udiv64_t::magic , 以及 tmp.

被这些函数引用 lmmp_is_prime_uint_() , 以及 lmmp_powmod_uint_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ _udiv64_gen_internal_()

static _udiv64_t _udiv64_gen_internal_ ( uint64_t  d,
int  branchfree 
)
inlinestatic

在文件 longlong.h507 行定义.

507 {
509 int shift;
510 uint64_t t;
511 clz_shl_u64(t, d, shift);
512 (void)t;
513 uint32_t floor_log_2_d = 63 - shift;
514
515 // Power of 2
516 if ((d & (d - 1)) == 0) {
517 // We need to subtract 1 from the shift value in case of an unsigned
518 // branchfree divider because there is a hardcoded right shift by 1
519 // in its division algorithm. Because of this we also need to add back
520 // 1 in its recovery algorithm.
521 result.magic = 0;
522 result.more = (uint8_t)(floor_log_2_d - (branchfree != 0));
523 } else {
524 uint64_t proposed_m, rem;
525 uint8_t more;
526 // (1 << (64 + floor_log_2_d)) / d
527 proposed_m = _udiv128by64to64_((uint64_t)1 << floor_log_2_d, 0, d, &rem);
528
529 const uint64_t e = d - rem;
530
531 // This power works if e < 2**floor_log_2_d.
532 if (!branchfree && e < ((uint64_t)1 << floor_log_2_d)) {
533 // This power works
534 more = (uint8_t)floor_log_2_d;
535 } else {
536 // We have to use the general 65-bit algorithm. We need to compute
537 // (2**power) / d. However, we already have (2**(power-1))/d and
538 // its remainder. By doubling both, and then correcting the
539 // remainder, we can compute the larger division.
540 // don't care about overflow here - in fact, we expect it
542 const uint64_t twice_rem = rem + rem;
543 if (twice_rem >= d || twice_rem < rem)
544 proposed_m += 1;
545 more = (uint8_t)(floor_log_2_d | _ADD_MARKER);
546 }
547 result.magic = 1 + proposed_m;
548 result.more = more;
549 // result.more's shift should in general be ceil_log_2_d. But if we
550 // used the smaller power, we subtract one from the shift because we're
551 // using the smaller power. If we're using the larger power, we
552 // subtract one from the shift because it's taken care of by the add
553 // indicator. So floor_log_2_d happens to be correct in both cases,
554 // which is why we do it outside of the if statement.
555 }
556 return result;
557}
#define _ADD_MARKER
Definition longlong.h:499
static uint64_t _udiv128by64to64_(uint64_t numhi, uint64_t numlo, uint64_t den, uint64_t *r)
Definition longlong.h:273
#define t

引用了 _ADD_MARKER, _udiv128by64to64_(), clz_shl_u64, _udiv64_t::magic, _udiv64_t::more , 以及 t.

被这些函数引用 _udiv64_gen().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ _udiv64by64_q_preinv()

static uint64_t _udiv64by64_q_preinv ( uint64_t  numer,
const _udiv64_t denom 
)
inlinestatic

在文件 longlong.h566 行定义.

566 {
567 uint64_t q = _umul64to64hi_(numer, denom->magic);
568 uint64_t t = ((numer - q) >> 1) + q;
569 return t >> denom->more;
570}
static uint64_t _umul64to64hi_(uint64_t a, uint64_t b)
Definition longlong.h:194

引用了 _umul64to64hi_(), _udiv64_t::magic, _udiv64_t::more , 以及 t.

被这些函数引用 lmmp_powmod_uint_(), miller_rabin_32(), trial_div13(), trial_div17(), trial_div19(), trial_div23(), trial_div29(), trial_div31(), trial_div37() , 以及 trial_div41().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ _umul128to128_()

static void _umul128to128_ ( uint64_t  a_high,
uint64_t  a_low,
uint64_t  b_high,
uint64_t  b_low,
uint64_t  rr[2] 
)
inlinestatic

在文件 longlong.h267 行定义.

267 {
268 _umul64to128_(a_low, b_low, rr, rr + 1);
269 rr[1] += a_low * b_high;
270 rr[1] += a_high * b_low;
271}
static void _umul64to128_(uint64_t a, uint64_t b, uint64_t *low, uint64_t *high)
Definition longlong.h:174

引用了 _umul64to128_().

被这些函数引用 lmmp_binvert_4_(), lmmp_binvert_unbalanced_2_() , 以及 lmmp_divexact_2_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ _umul128to256_()

static void _umul128to256_ ( uint64_t  a_high,
uint64_t  a_low,
uint64_t  b_high,
uint64_t  b_low,
uint64_t  rr[4] 
)
inlinestatic

在文件 longlong.h212 行定义.

212 {
213 uint64_t p1_low, p1_high; // p1 = a_low × b_high
214 uint64_t p2_low, p2_high; // p2 = a_high × b_low
215 _umul64to128_(a_low, b_low, rr, rr + 1);
218 _umul64to128_(a_high, b_high, rr + 2, rr + 3);
219 /*
220 | res0 | res1 | res2 | res3 |
221 | p0l | p0h | | |
222 | p1l | p1h | |
223 | p2l | p2h | |
224 | | p3l | p3h |
225 */
226 rr[1] += p1_low;
227 uint64_t carry = (rr[1] < p1_low) ? 1 : 0;
228 rr[1] += p2_low;
229 carry += (rr[1] < p2_low) ? 1 : 0;
230
231 rr[2] += carry;
232 carry = (rr[2] < carry) ? 1 : 0;
233 rr[2] += p1_high;
234 carry += (rr[2] < p1_high) ? 1 : 0;
235 rr[2] += p2_high;
236 carry += (rr[2] < p2_high) ? 1 : 0;
237
238 rr[3] += carry;
239}

引用了 _umul64to128_().

被这些函数引用 lmmp_binvert_4_(), lmmp_binvert_unbalanced_2_() , 以及 lmmp_divexact_2_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ _umul64to128_()

static void _umul64to128_ ( uint64_t  a,
uint64_t  b,
uint64_t *  low,
uint64_t *  high 
)
inlinestatic

在文件 longlong.h174 行定义.

174 {
175#if (defined(__GNUC__) || defined(__clang__))
177 *low = (uint64_t)prod;
178 *high = (uint64_t)(prod >> 64);
179#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
180 *low = _umul128(a, b, high);
181#else
182 uint64_t ah = a >> 32, bh = b >> 32;
183 a = (uint32_t)a, b = (uint32_t)b;
184 uint64_t r0 = a * b, r1 = a * bh, r2 = ah * b, r3 = ah * bh;
185 r3 += (r1 >> 32) + (r2 >> 32);
186 r1 = (uint32_t)r1, r2 = (uint32_t)r2;
187 r1 += r2;
188 r1 += (r0 >> 32);
189 *high = r3 + (r1 >> 32);
190 *low = (r1 << 32) | (uint32_t)r0;
191#endif
192}
#define r2
#define r3

引用了 r0, r1, r2 , 以及 r3.

被这些函数引用 _umul128to128_(), _umul128to192_(), _umul128to256_(), _usqr128to256_(), lmmp_addmul_1_(), lmmp_binvert_2_(), lmmp_binvert_4_(), lmmp_binvert_unbalanced_1_(), lmmp_divexact_1_(), lmmp_inv_2_1_(), lmmp_mul_1_(), lmmp_mul_basecase_(), lmmp_mulmod_ulong_(), lmmp_sqr_basecase_(), lmmp_submul_1_(), pcg64_128_action(), umul128x64_tohi128() , 以及 umul192x128_tohi192().

+ 这是这个函数的调用关系图:

◆ _umul64to64hi_()

static uint64_t _umul64to64hi_ ( uint64_t  a,
uint64_t  b 
)
inlinestatic

在文件 longlong.h194 行定义.

194 {
195#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__)
197 return (uint64_t)(t >> 64);
198#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
199 return __umulh(a, b);
200#else
201 uint64_t ah = a >> 32, bh = b >> 32;
202 a = (uint32_t)a, b = (uint32_t)b;
203 uint64_t r0 = a * b, r1 = a * bh, r2 = ah * b, r3 = ah * bh;
204 r3 += (r1 >> 32) + (r2 >> 32);
205 r1 = (uint32_t)r1, r2 = (uint32_t)r2;
206 r1 += r2;
207 r1 += (r0 >> 32);
208 return r3 + (r1 >> 32);
209#endif
210}

引用了 r0, r1, r2, r3 , 以及 t.

被这些函数引用 _udiv64by64_q_preinv().

+ 这是这个函数的调用关系图:

◆ _usqr128to256_()

static void _usqr128to256_ ( uint64_t  a_high,
uint64_t  a_low,
uint64_t  rr[4] 
)
inlinestatic

在文件 longlong.h241 行定义.

241 {
242 uint64_t p1_low, p1_high; // p1 = a_low × a_high
243 _umul64to128_(a_low, a_low, rr, rr + 1);
245 _umul64to128_(a_high, a_high, rr + 2, rr + 3);
246 /*
247 | res0 | res1 | res2 | res3 |
248 | p0l | p0h | | |
249 | p1l | p1h | |
250 | p1l | p1h | |
251 | | p3l | p3h |
252 */
253 rr[3] += p1_high >> 63;
254 p1_high = (p1_high << 1) | (p1_low >> 63);
255 p1_low <<= 1;
256 rr[1] += p1_low;
257 uint64_t carry = (rr[1] < p1_low) ? 1 : 0;
258
259 rr[2] += carry;
260 carry = (rr[2] < carry) ? 1 : 0;
261 rr[2] += p1_high;
262 carry += (rr[2] < p1_high) ? 1 : 0;
263
264 rr[3] += carry;
265}

引用了 _umul64to128_().

+ 函数调用图: