Skip to content

Commit e5c2df9

Browse files
Justus2308andrewrk
authored andcommitted
std.math.big.int: fix format functions
1 parent 16fc083 commit e5c2df9

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

lib/std/math/big/int.zig

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2032,7 +2032,11 @@ pub const Mutable = struct {
20322032
return formatNumber(self, w, .{});
20332033
}
20342034

2035-
pub fn formatNumber(self: Const, w: *std.Io.Writer, n: std.fmt.Number) std.Io.Writer.Error!void {
2035+
/// If the absolute value of integer is greater than or equal to `pow(2, 64 * @sizeOf(usize) * 8)`,
2036+
/// this function will fail to print the string, printing "(BigInt)" instead of a number.
2037+
/// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
2038+
/// See `Const.toString` and `Const.toStringAlloc` for a way to print big integers without failure.
2039+
pub fn formatNumber(self: Mutable, w: *std.Io.Writer, n: std.fmt.Number) std.Io.Writer.Error!void {
20362040
return self.toConst().formatNumber(w, n);
20372041
}
20382042
};
@@ -2321,6 +2325,10 @@ pub const Const = struct {
23212325
return .{ normalized_res.reconstruct(if (self.positive) .positive else .negative), exactness };
23222326
}
23232327

2328+
pub fn format(self: Const, w: *std.Io.Writer) std.Io.Writer.Error!void {
2329+
return self.formatNumber(w, .{});
2330+
}
2331+
23242332
/// If the absolute value of integer is greater than or equal to `pow(2, 64 * @sizeOf(usize) * 8)`,
23252333
/// this function will fail to print the string, printing "(BigInt)" instead of a number.
23262334
/// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
@@ -4625,3 +4633,29 @@ fn testOneShiftCaseAliasing(func: fn ([]Limb, []const Limb, usize) usize, case:
46254633
try std.testing.expectEqualSlices(Limb, expected, r[base .. base + len]);
46264634
}
46274635
}
4636+
4637+
test "format" {
4638+
var a: Managed = try .init(std.testing.allocator);
4639+
defer a.deinit();
4640+
4641+
try a.set(123);
4642+
try testFormat(a, "123");
4643+
4644+
try a.set(-123);
4645+
try testFormat(a, "-123");
4646+
4647+
try a.set(20000000000000000000); // > maxInt(u64)
4648+
try testFormat(a, "20000000000000000000");
4649+
4650+
try a.set(1 << 64 * @sizeOf(usize) * 8);
4651+
try testFormat(a, "(BigInt)");
4652+
4653+
try a.set(-(1 << 64 * @sizeOf(usize) * 8));
4654+
try testFormat(a, "(BigInt)");
4655+
}
4656+
4657+
fn testFormat(a: Managed, expected: []const u8) !void {
4658+
try std.testing.expectFmt(expected, "{f}", .{a});
4659+
try std.testing.expectFmt(expected, "{f}", .{a.toMutable()});
4660+
try std.testing.expectFmt(expected, "{f}", .{a.toConst()});
4661+
}

0 commit comments

Comments
 (0)