zig
zig copied to clipboard
std.math.big.int.Managed: panic during printing of large integers
Zig Version
0.13.0-dev.44+9d64332a5
Steps to Reproduce and Observed Behavior
const std = @import("std");
/// 2**2624
const large_number = "7992978086026108130997763255271161054080232827028600926878720894626652959801126270181797858326539991808408501955736107211154089990880864133038492082242191005916626161786978154573691945393533534978528355014105088982291537161053152762247775679110034623793214880221822114791083764160121545158487346802968250797762918640822953726116267698324397972187098127467165312071016262496415446666524545989368685880483796761627291294104820031154953033398353527633219044576542971747588932919682723327383286444096495073061099816572815545646462399372759381873394869194849561982777842027295205127497543421120520478507405494463168887803685629450345554505826605909746350048296170530667798848741774249115342399979893391684184998084322821589461452070845054017545885544579571298686351226398527864005606439403913216";
test {
// BigInt docs state:
// If the integer is larger than `pow(2, 64 * @sizeOf(usize) * 8), this function [format] will fail
// to print the string, printing "(BigInt)" instead of a number.
comptime std.debug.assert(2624 < 64 * @sizeOf(usize) * 8); // Tested on 64 bit system
var managed = try std.math.big.int.Managed.init(std.testing.allocator);
defer managed.deinit();
try managed.setString(10, large_number);
var output = std.ArrayList(u8).init(std.testing.allocator);
defer output.deinit();
const writer = output.writer();
try writer.print("{d}", .{managed});
}
ehaas@computer ~ % zig test test.zig
Test [1/1] test.test_0... thread 15309777 panic: index out of bounds: index 44, len 42
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/std/math/big/int.zig:1083:41: 0x102ddafa1 in divTrunc (test)
var x = a.toMutable(limbs_buffer[0..sep]);
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/std/math/big/int.zig:2341:27: 0x102da76d8 in toString (test)
q.divTrunc(&r, q.toConst(), b, rest_of_the_limbs_buf);
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/std/math/big/int.zig:2247:34: 0x102da6789 in format__anon_7958 (test)
const len = self.toString(&buf, base, case, &limbs);
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/std/math/big/int.zig:2817:37: 0x102da7d6c in format__anon_7957 (test)
return self.toConst().format(fmt, options, out_stream);
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/std/fmt.zig:494:32: 0x102d76c1d in formatType__anon_5779 (test)
return try value.format(actual_fmt, options, writer);
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/std/fmt.zig:185:23: 0x102d6c380 in format__anon_4188 (test)
try formatType(
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/std/io/Writer.zig:23:26: 0x102d66ee0 in print__anon_3134 (test)
return std.fmt.format(self, format, args);
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/std/io.zig:324:47: 0x102d64e86 in test_0 (test)
return @errorCast(self.any().print(format, args));
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/compiler/test_runner.zig:158:25: 0x102d734b8 in mainTerminal (test)
if (test_fn.func()) |_| {
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/compiler/test_runner.zig:35:28: 0x102d6757c in main (test)
return mainTerminal();
^
/Users/ehaas/local/zig-macos-x86_64-0.13.0-dev.44+9d64332a5/lib/std/start.zig:501:22: 0x102d6720b in main (test)
root.main();
^
Expected Behavior
No crash and number correctly printed to output buffer.
It works if the number is (2**2624) - 1 so if the docs were instead changed to "greater than or equal to" that would also resolve that part of the mismatch.
However, the stated behavior of printing "(BigInt)" should at least let the test pass even on larger values.