Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion lib/std/math/big/int.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2032,7 +2032,11 @@ pub const Mutable = struct {
return formatNumber(self, w, .{});
}

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

pub fn format(self: Const, w: *std.Io.Writer) std.Io.Writer.Error!void {
return self.formatNumber(w, .{});
}

/// If the absolute value of integer is greater than or equal to `pow(2, 64 * @sizeOf(usize) * 8)`,
/// this function will fail to print the string, printing "(BigInt)" instead of a number.
/// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
Expand Down Expand Up @@ -4625,3 +4633,29 @@ fn testOneShiftCaseAliasing(func: fn ([]Limb, []const Limb, usize) usize, case:
try std.testing.expectEqualSlices(Limb, expected, r[base .. base + len]);
}
}

test "format" {
var a: Managed = try .init(std.testing.allocator);
defer a.deinit();

try a.set(123);
try testFormat(a, "123");

try a.set(-123);
try testFormat(a, "-123");

try a.set(20000000000000000000); // > maxInt(u64)
try testFormat(a, "20000000000000000000");

try a.set(1 << 64 * @sizeOf(usize) * 8);
try testFormat(a, "(BigInt)");

try a.set(-(1 << 64 * @sizeOf(usize) * 8));
try testFormat(a, "(BigInt)");
}

fn testFormat(a: Managed, expected: []const u8) !void {
try std.testing.expectFmt(expected, "{f}", .{a});
try std.testing.expectFmt(expected, "{f}", .{a.toMutable()});
try std.testing.expectFmt(expected, "{f}", .{a.toConst()});
}