aboutsummaryrefslogtreecommitdiff
path: root/lib/std/math
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-07-05 10:43:14 -0700
committerAndrew Kelley <andrew@ziglang.org>2025-07-07 22:43:53 -0700
commit5378fdb153bc76990105e3640e7725e434e8cdee (patch)
tree9791e08538c10c521f5634ed79e3b369fcd004df /lib/std/math
parent4ccc6f2b5777afd06f0fddbea4e0e0d0c92b007d (diff)
downloadzig-5378fdb153bc76990105e3640e7725e434e8cdee.tar.gz
zig-5378fdb153bc76990105e3640e7725e434e8cdee.zip
std.fmt: fully remove format string from format methods
Introduces `std.fmt.alt` which is a helper for calling alternate format methods besides one named "format".
Diffstat (limited to 'lib/std/math')
-rw-r--r--lib/std/math/big/int.zig48
-rw-r--r--lib/std/math/big/int_test.zig14
2 files changed, 27 insertions, 35 deletions
diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig
index 3e6d66321f..000b578dc0 100644
--- a/lib/std/math/big/int.zig
+++ b/lib/std/math/big/int.zig
@@ -2317,46 +2317,40 @@ pub const Const = struct {
return .{ normalized_res.reconstruct(if (self.positive) .positive else .negative), exactness };
}
- /// To allow `std.fmt.format` to work with this type.
/// 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 `toString` and `toStringAlloc` for a way to print big integers without failure.
- pub fn format(self: Const, w: *std.io.Writer, comptime fmt: []const u8) std.io.Writer.Error!void {
- comptime var base = 10;
- comptime var case: std.fmt.Case = .lower;
-
- if (fmt.len == 0 or comptime mem.eql(u8, fmt, "d")) {
- base = 10;
- case = .lower;
- } else if (comptime mem.eql(u8, fmt, "b")) {
- base = 2;
- case = .lower;
- } else if (comptime mem.eql(u8, fmt, "x")) {
- base = 16;
- case = .lower;
- } else if (comptime mem.eql(u8, fmt, "X")) {
- base = 16;
- case = .upper;
- } else {
- std.fmt.invalidFmtError(fmt, self);
- }
-
+ pub fn print(self: Const, w: *std.io.Writer, base: u8, case: std.fmt.Case) std.io.Writer.Error!void {
const available_len = 64;
if (self.limbs.len > available_len)
return w.writeAll("(BigInt)");
- var limbs: [calcToStringLimbsBufferLen(available_len, base)]Limb = undefined;
+ var limbs: [calcToStringLimbsBufferLen(available_len, 10)]Limb = undefined;
const biggest: Const = .{
.limbs = &([1]Limb{comptime math.maxInt(Limb)} ** available_len),
.positive = false,
};
- var buf: [biggest.sizeInBaseUpperBound(base)]u8 = undefined;
+ var buf: [biggest.sizeInBaseUpperBound(2)]u8 = undefined;
const len = self.toString(&buf, base, case, &limbs);
return w.writeAll(buf[0..len]);
}
+ const Format = struct {
+ int: Const,
+ base: u8,
+ case: std.fmt.Case,
+
+ pub fn default(f: Format, w: *std.io.Writer) std.io.Writer.Error!void {
+ return print(f.int, w, f.base, f.case);
+ }
+ };
+
+ pub fn fmt(self: Const, base: u8, case: std.fmt.Case) std.fmt.Formatter(Format, Format.default) {
+ return .{ .data = .{ .int = self, .base = base, .case = case } };
+ }
+
/// Converts self to a string in the requested base.
/// Caller owns returned memory.
/// Asserts that `base` is in the range [2, 36].
@@ -2924,12 +2918,16 @@ pub const Managed = struct {
}
/// To allow `std.fmt.format` to work with `Managed`.
+ pub fn format(self: Managed, w: *std.io.Writer, comptime f: []const u8) std.io.Writer.Error!void {
+ return self.toConst().format(w, f);
+ }
+
/// 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 `toString` and `toStringAlloc` for a way to print big integers without failure.
- pub fn format(self: Managed, w: *std.io.Writer, comptime f: []const u8) std.io.Writer.Error!void {
- return self.toConst().format(w, f);
+ pub fn fmt(self: Managed, base: u8, case: std.fmt.Case) std.fmt.Formatter(Const.Format, Const.Format.default) {
+ return .{ .data = .{ .int = self.toConst(), .base = base, .case = case } };
}
/// Returns math.Order.lt, math.Order.eq, math.Order.gt if |a| < |b|, |a| ==
diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig
index 0f688b359d..58f5a01a05 100644
--- a/lib/std/math/big/int_test.zig
+++ b/lib/std/math/big/int_test.zig
@@ -3813,14 +3813,8 @@ test "(BigInt) positive" {
try a.pow(&a, 64 * @sizeOf(Limb) * 8);
try b.sub(&a, &c);
- const a_fmt = try std.fmt.allocPrintSentinel(testing.allocator, "{fd}", .{a}, 0);
- defer testing.allocator.free(a_fmt);
-
- const b_fmt = try std.fmt.allocPrintSentinel(testing.allocator, "{fd}", .{b}, 0);
- defer testing.allocator.free(b_fmt);
-
- try testing.expect(mem.eql(u8, a_fmt, "(BigInt)"));
- try testing.expect(!mem.eql(u8, b_fmt, "(BigInt)"));
+ try testing.expectFmt("(BigInt)", "{f}", .{a.fmt(10, .lower)});
+ try testing.expectFmt("1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085903001302413467189726673216491511131602920781738033436090243804708340403154190335", "{f}", .{b.fmt(10, .lower)});
}
test "(BigInt) negative" {
@@ -3838,10 +3832,10 @@ test "(BigInt) negative" {
a.negate();
try b.add(&a, &c);
- const a_fmt = try std.fmt.allocPrintSentinel(testing.allocator, "{fd}", .{a}, 0);
+ const a_fmt = try std.fmt.allocPrint(testing.allocator, "{f}", .{a.fmt(10, .lower)});
defer testing.allocator.free(a_fmt);
- const b_fmt = try std.fmt.allocPrintSentinel(testing.allocator, "{fd}", .{b}, 0);
+ const b_fmt = try std.fmt.allocPrint(testing.allocator, "{f}", .{b.fmt(10, .lower)});
defer testing.allocator.free(b_fmt);
try testing.expect(mem.eql(u8, a_fmt, "(BigInt)"));