Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std.math.big.int sqrt panic #17858

Closed
guidovranken opened this issue Nov 4, 2023 · 4 comments · Fixed by #17906 or #17919
Closed

std.math.big.int sqrt panic #17858

guidovranken opened this issue Nov 4, 2023 · 4 comments · Fixed by #17906 or #17919
Labels
bug Observed behavior contradicts documented or intended behavior standard library This issue involves writing Zig code for the standard library.
Milestone

Comments

@guidovranken
Copy link

Zig Version

zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96

Steps to Reproduce and Observed Behavior

sqrt added by @mizuochik in 4422af8

Sqrt of 0

const std = @import("std");

pub fn main() !void {
    const allocator = std.heap.page_allocator;

    var a = std.math.big.int.Managed.initSet(allocator, @as(usize, 1)) catch unreachable;
    defer a.deinit();

    var res = std.math.big.int.Managed.initSet(allocator, @as(usize, 1)) catch unreachable;
    defer res.deinit();

    a.setString(10, "0") catch unreachable;

    res.sqrt(&a) catch unreachable;
}

Output:

thread 1853221 panic: integer overflow
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/math/big/int.zig:70:39: 0x21fb00 in calcSqrtLimbsBufferLen (p)
    const a_limb_count = (a_bit_count - 1) / limb_bits + 1;
                                      ^
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/math/big/int.zig:3231:52: 0x21f818 in sqrt (p)
        const needed_limbs = calcSqrtLimbsBufferLen(a.bitCountAbs());
                                                   ^
/home/jhg/cf-zig-sqrt/p/p.zig:14:13: 0x220b78 in main (p)
    res.sqrt(&a) catch unreachable;
            ^
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/start.zig:581:37: 0x21e237 in posixCallMainAndExit (p)
            const result = root.main() catch |err| {
                                    ^
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/start.zig:249:5: 0x21dd61 in _start (p)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)
Aborted (core dumped)

Sqrt of large value

const std = @import("std");

pub fn main() !void {
    const allocator = std.heap.page_allocator;

    var a = std.math.big.int.Managed.initSet(allocator, @as(usize, 1)) catch unreachable;
    defer a.deinit();

    var res = std.math.big.int.Managed.initSet(allocator, @as(usize, 1)) catch unreachable;
    defer res.deinit();

    a.setString(10, "136036462105870278006290938611834481486") catch unreachable;

    res.sqrt(&a) catch unreachable;
}

Output:

thread 1853271 panic: index out of bounds: index 3, len 2
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/math/big/int.zig:1975:36: 0x22927d in normalize (p)
        r.len = llnormalize(r.limbs[0..length]);
                                   ^
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/math/big/int.zig:1100:20: 0x225702 in shiftLeft (p)
        r.normalize(a.limbs.len + (shift / limb_bits) + 1);
                   ^
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/math/big/int.zig:1385:24: 0x22039b in sqrt (p)
            m.shiftLeft(m.toConst(), shift); // u must be >= ⌊√a⌋, and should be as small as possible for efficiency
                       ^
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/math/big/int.zig:3238:15: 0x21fa20 in sqrt (p)
        m.sqrt(a.toConst(), limbs_buffer);
              ^
/home/jhg/cf-zig-sqrt/p/p.zig:14:13: 0x220b78 in main (p)
    res.sqrt(&a) catch unreachable;
            ^
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/start.zig:581:37: 0x21e237 in posixCallMainAndExit (p)
            const result = root.main() catch |err| {
                                    ^
/home/jhg/cf-zig-sqrt/zig-linux-x86_64-0.12.0-dev.1396+f6de3ec96/lib/std/start.zig:249:5: 0x21dd61 in _start (p)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)
Aborted (core dumped)

Expected Behavior

No panics

@guidovranken guidovranken added the bug Observed behavior contradicts documented or intended behavior label Nov 4, 2023
@guidovranken guidovranken changed the title std.math.big.int divFloor panic std.math.big.int sqrt panic Nov 4, 2023
@mizuochik
Copy link
Contributor

@guidovranken Thanks for reporting. I'll fix it.

@Vexu Vexu added the standard library This issue involves writing Zig code for the standard library. label Nov 6, 2023
@Vexu Vexu added this to the 0.13.0 milestone Nov 6, 2023
@guidovranken
Copy link
Author

This only fixes sqrt(0), not sqrt with larger values. Please read my bug report again. There are reproducers for these two distinct issues.

@tisonkun
Copy link
Contributor

tisonkun commented Nov 7, 2023

@guidovranken @Vexu it's about an offset by one issue for the result take more than usize bits. I propose a fix at #17919.

@guidovranken
Copy link
Author

Confirmed that #17919 fully resolves the issues with sqrt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior standard library This issue involves writing Zig code for the standard library.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants