IntRootRem
Description
Compute an integer root and the leftover remainder.
Parameters
| Name | Direction | Description |
|---|---|---|
root |
out | Destination for the root |
remainder |
out | Destination for the remainder |
value |
in | Input value |
degree |
in | Root degree |
Usage example (from documentation)
IntRootRem(&root, &rem, &value, 3);Success
Returns true. *root holds floor(value^(1/degree)), *remainder holds value - root^degree.
Failure
Returns false on degree == 0 or allocator OOM. *root / *remainder are left untouched.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Int.c:1992:
}
bool IntRootRem(Int *root, Int *remainder, const Int *value, u64 degree) {
ValidateInt(root);
ValidateInt(remainder);- In
Int.c:2168:
Int remainder = IntInit(IntAllocator(result));
if (!IntRootRem(&root, &remainder, value, degree)) {
IntDeinit(&root);
IntDeinit(&remainder);- In
Int.c:2180:
bool IntSqrtRem(Int *root, Int *remainder, const Int *value) {
return IntRootRem(root, remainder, value, 2);
}- In
Int.c:2224:
bool exact = false;
if (!IntRootRem(&root, &remainder, value, degree)) {
IntDeinit(&root);
IntDeinit(&remainder);- In
Math.c:545:
bool test_int_root_rem(void) {
WriteFmt("Testing IntRootRem\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Math.c:553:
Int remainder = IntInit(&alloc.base);
IntRootRem(&root, &remainder, &value, 3);
bool result = IntToU64(&root) == 5;- In
Math.c:1013:
Int root = IntFrom(99, &alloc.base);
Int remainder = IntFrom(77, &alloc.base);
bool result = !IntRootRem(&root, &remainder, &value, 0);
result = result && (IntCompare(&root, 99) == 0);- In
Math.c:1947:
// (lines 1712/1713) leaves the stale value and fails the assertion.
static bool test_m2_root_rem_zero_value_resets_outputs(void) {
WriteFmt("Testing IntRootRem zero-value resets both outputs\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Math.c:1955:
Int remainder = IntFrom(77, &alloc.base);
bool ok = IntRootRem(&root, &remainder, &value, 3);
bool result = ok;
result = result && (IntCompare(&root, 0) == 0);- In
Math.c:1972:
// root. Also exercises the loop midpoint shift (1766).
static bool test_m2_root_rem_perfect_square_large(void) {
WriteFmt("Testing IntRootRem 10000^(1/2) == 100 exact\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Math.c:1980:
Int remainder = IntInit(&alloc.base);
bool ok = IntRootRem(&root, &remainder, &value, 2);
bool result = ok;
result = result && (IntToU64(&root) == 100);- In
Math.c:1995:
// further constrain the high_shift bit-length math and the binary search.
static bool test_m2_root_rem_perfect_cube(void) {
WriteFmt("Testing IntRootRem 1000^(1/3) == 10 exact\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Math.c:2003:
Int remainder = IntInit(&alloc.base);
bool ok = IntRootRem(&root, &remainder, &value, 3);
bool result = ok;
result = result && (IntToU64(&root) == 10);- In
Math.c:2019:
// the midpoint/compare path produces a wrong root or remainder.
static bool test_m2_root_rem_nonperfect_cube_remainder(void) {
WriteFmt("Testing IntRootRem 1001^(1/3) == 10 rem 1\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Math.c:2027:
Int remainder = IntInit(&alloc.base);
bool ok = IntRootRem(&root, &remainder, &value, 3);
bool result = ok;
result = result && (IntToU64(&root) == 10);- In
Math.c:2042:
// search to settle one below 10 and validates the remainder subtraction path.
static bool test_m2_root_rem_just_below_perfect_cube(void) {
WriteFmt("Testing IntRootRem 999^(1/3) == 9 rem 270\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Math.c:2050:
Int remainder = IntInit(&alloc.base);
bool ok = IntRootRem(&root, &remainder, &value, 3);
bool result = ok;
result = result && (IntToU64(&root) == 9);- In
Math.c:2065:
// 1000000^(1/4): 31^4=923521, 32^4=1048576 -> root 31, rem 1000000-923521=76479.
static bool test_m2_root_rem_fourth_root_large(void) {
WriteFmt("Testing IntRootRem 1000000^(1/4) == 31 rem 76479\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Math.c:2073:
Int remainder = IntInit(&alloc.base);
bool ok = IntRootRem(&root, &remainder, &value, 4);
bool result = ok;
result = result && (IntToU64(&root) == 31);- In
Math.c:2928:
// mutant returns a wrong (too small) root.
bool test_fe_1730_root_rem_large_value(void) {
WriteFmt("Testing IntRootRem bit-length derived bound (large value)\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Math.c:4035:
Int rem = IntFrom(9u, a);
bool ok = IntRootRem(&root, &rem, &v, 3); // 100^3 = 1e6
ok = ok && IntToU64(&root) == 100u && IntIsZero(&rem);- In
Math.c:4055:
Int rem = IntFrom(9u, a);
bool ok = IntRootRem(&root, &rem, &v, 3); // cbrt(1000)=10 exact actually
ok = ok && IntToU64(&root) == 10u && IntIsZero(&rem);- In
Math.c:4060:
// and a genuinely inexact one
Int v2 = IntFrom(999u, a);
ok = ok && IntRootRem(&root, &rem, &v2, 3);
ok = ok && IntToU64(&root) == 9u && IntToU64(&rem) == 999u - 729u;- In
Access.c:206:
// the int_replace removals (1725/1726).
static bool test_m2_root_rem_degree_one_clones_value(void) {
WriteFmt("Testing IntRootRem degree==1 clones value, zero remainder\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
Access.c:214:
Int remainder = IntFrom(77, &alloc.base);
bool ok = IntRootRem(&root, &remainder, &value, 1);
bool result = ok;
result = result && (IntToU64(&root) == 12345);
Last updated on