| ... | ... | @@ -2032,7 +2032,11 @@ pub const Mutable = struct { |
| 2032 | 2032 | return formatNumber(self, w, .{}); |
| 2033 | 2033 | } |
| 2034 | 2034 | |
| 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 { |
| 2036 | 2040 | return self.toConst().formatNumber(w, n); |
| 2037 | 2041 | } |
| 2038 | 2042 | }; |
| ... | ... | @@ -2321,6 +2325,10 @@ pub const Const = struct { |
| 2321 | 2325 | return .{ normalized_res.reconstruct(if (self.positive) .positive else .negative), exactness }; |
| 2322 | 2326 | } |
| 2323 | 2327 | |
| 2328 | pub fn format(self: Const, w: *std.Io.Writer) std.Io.Writer.Error!void { |
| 2329 | return self.formatNumber(w, .{}); |
| 2330 | } |
| 2331 | |
| 2324 | 2332 | /// If the absolute value of integer is greater than or equal to `pow(2, 64 * @sizeOf(usize) * 8)`, |
| 2325 | 2333 | /// this function will fail to print the string, printing "(BigInt)" instead of a number. |
| 2326 | 2334 | /// 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: |
| 4625 | 4633 | try std.testing.expectEqualSlices(Limb, expected, r[base .. base + len]); |
| 4626 | 4634 | } |
| 4627 | 4635 | } |
| 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 | } |