| ... | ... | @@ -906,24 +906,31 @@ fn formatUnicodeCodepoint(c: u21, options: FormatOptions, writer: anytype) !void |
| 906 | 906 | } |
| 907 | 907 | |
| 908 | 908 | fn formatFloatValue(value: anytype, comptime fmt: []const u8, options: FormatOptions, writer: anytype) !void { |
| 909 | | var buf: [std.fmt.format_float.bufferSize(.decimal, f64)]u8 = undefined; |
| 909 | const v = switch (@TypeOf(value)) { |
| 910 | comptime_float => @as(f128, value), // comptime_float internally is a f128; this preserves precision. |
| 911 | else => value, |
| 912 | }; |
| 913 | const T = @TypeOf(v); |
| 914 | comptime std.debug.assert(@typeInfo(T) == .float); |
| 915 | const I = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } }); |
| 916 | const DT = if (@bitSizeOf(T) <= 64) u64 else u128; |
| 917 | const tables = switch (DT) { |
| 918 | u64 => &std.fmt.float.Backend64_TablesFull, |
| 919 | u128 => &std.fmt.float.Backend128_Tables, |
| 920 | else => unreachable, |
| 921 | }; |
| 922 | const has_explicit_leading_bit = std.math.floatMantissaBits(T) - std.math.floatFractionalBits(T) != 0; |
| 923 | const d = std.fmt.float.binaryToDecimal(DT, @as(I, @bitCast(v)), std.math.floatMantissaBits(T), std.math.floatExponentBits(T), has_explicit_leading_bit, tables); |
| 924 | var buf: [std.fmt.float.bufferSize(.decimal, T)]u8 = undefined; |
| 910 | 925 | |
| 911 | 926 | if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "e")) { |
| 912 | | const s = std.fmt.formatFloat(&buf, value, .{ .mode = .scientific, .precision = options.precision }) catch |err| switch (err) { |
| 913 | | error.BufferTooSmall => "(float)", |
| 914 | | }; |
| 915 | | return formatBuf(s, options, writer); |
| 927 | try writer.writeAll(std.fmt.float.formatScientific(DT, &buf, d, options.precision) catch unreachable); |
| 916 | 928 | } else if (comptime std.mem.eql(u8, fmt, "d")) { |
| 917 | | const s = std.fmt.formatFloat(&buf, value, .{ .mode = .decimal, .precision = options.precision }) catch |err| switch (err) { |
| 918 | | error.BufferTooSmall => "(float)", |
| 919 | | }; |
| 920 | | return formatBuf(s, options, writer); |
| 929 | try writer.writeAll(std.fmt.float.formatDecimal(DT, &buf, d, options.precision) catch unreachable); |
| 921 | 930 | } else if (comptime std.mem.eql(u8, fmt, "x")) { |
| 922 | | var buf_stream: nio.FixedBufferStream([]u8) = .init(&buf); |
| 923 | | std.fmt.formatFloatHexadecimal(value, options, &buf_stream) catch |err| switch (err) { |
| 924 | | error.NoSpaceLeft => unreachable, |
| 925 | | }; |
| 926 | | return formatBuf(buf_stream.written(), options, writer); |
| 931 | var w: std.Io.Writer = .fixed(&buf); |
| 932 | w.printFloatHex(v, .lower, options.precision) catch unreachable; |
| 933 | try writer.writeAll(buf[0..w.end]); |
| 927 | 934 | } else { |
| 928 | 935 | invalidFmtError(fmt, value); |
| 929 | 936 | } |