mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
std.math.big.int.Managed: adjust size of arg for limbs_buffer in format()
This commit is contained in:
parent
33d7815813
commit
aa07366513
@ -2201,8 +2201,8 @@ pub const Const = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// To allow `std.fmt.format` to work with this type.
|
/// To allow `std.fmt.format` to work with this type.
|
||||||
/// If the integer is larger than `pow(2, 64 * @sizeOf(usize) * 8), this function will fail
|
/// If the absolute value of integer is greater than or equal to `pow(2, 64 * @sizeOf(usize) * 8)`,
|
||||||
/// to print the string, printing "(BigInt)" instead of a number.
|
/// 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.
|
/// 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.
|
/// See `toString` and `toStringAlloc` for a way to print big integers without failure.
|
||||||
pub fn format(
|
pub fn format(
|
||||||
@ -2231,13 +2231,11 @@ pub const Const = struct {
|
|||||||
std.fmt.invalidFmtError(fmt, self);
|
std.fmt.invalidFmtError(fmt, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
var limbs: [128]Limb = undefined;
|
const available_len = 64;
|
||||||
const needed_limbs = calcDivLimbsBufferLen(self.limbs.len, 1);
|
if (self.limbs.len > available_len)
|
||||||
if (needed_limbs > limbs.len)
|
|
||||||
return out_stream.writeAll("(BigInt)");
|
return out_stream.writeAll("(BigInt)");
|
||||||
|
|
||||||
// This is the inverse of calcDivLimbsBufferLen
|
var limbs: [calcToStringLimbsBufferLen(available_len, base)]Limb = undefined;
|
||||||
const available_len = (limbs.len / 3) - 2;
|
|
||||||
|
|
||||||
const biggest: Const = .{
|
const biggest: Const = .{
|
||||||
.limbs = &([1]Limb{comptime math.maxInt(Limb)} ** available_len),
|
.limbs = &([1]Limb{comptime math.maxInt(Limb)} ** available_len),
|
||||||
@ -2804,8 +2802,8 @@ pub const Managed = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// To allow `std.fmt.format` to work with `Managed`.
|
/// To allow `std.fmt.format` to work with `Managed`.
|
||||||
/// If the integer is larger than `pow(2, 64 * @sizeOf(usize) * 8), this function will fail
|
/// If the absolute value of integer is greater than or equal to `pow(2, 64 * @sizeOf(usize) * 8)`,
|
||||||
/// to print the string, printing "(BigInt)" instead of a number.
|
/// 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.
|
/// 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.
|
/// See `toString` and `toStringAlloc` for a way to print big integers without failure.
|
||||||
pub fn format(
|
pub fn format(
|
||||||
|
|||||||
@ -3232,3 +3232,52 @@ test "Managed sqrt(n) succeed with res.bitCountAbs() >= usize bits" {
|
|||||||
try expected.setString(10, "11663466984815033033");
|
try expected.setString(10, "11663466984815033033");
|
||||||
try std.testing.expectEqual(std.math.Order.eq, expected.order(res));
|
try std.testing.expectEqual(std.math.Order.eq, expected.order(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "(BigInt) positive" {
|
||||||
|
var a = try Managed.initSet(testing.allocator, 2);
|
||||||
|
defer a.deinit();
|
||||||
|
|
||||||
|
var b = try Managed.init(testing.allocator);
|
||||||
|
defer b.deinit();
|
||||||
|
|
||||||
|
var c = try Managed.initSet(testing.allocator, 1);
|
||||||
|
defer c.deinit();
|
||||||
|
|
||||||
|
// a = pow(2, 64 * @sizeOf(usize) * 8), b = a - 1
|
||||||
|
try a.pow(&a, 64 * @sizeOf(Limb) * 8);
|
||||||
|
try b.sub(&a, &c);
|
||||||
|
|
||||||
|
const a_fmt = try std.fmt.allocPrintZ(testing.allocator, "{d}", .{a});
|
||||||
|
defer testing.allocator.free(a_fmt);
|
||||||
|
|
||||||
|
const b_fmt = try std.fmt.allocPrintZ(testing.allocator, "{d}", .{b});
|
||||||
|
defer testing.allocator.free(b_fmt);
|
||||||
|
|
||||||
|
try testing.expect(mem.eql(u8, a_fmt, "(BigInt)"));
|
||||||
|
try testing.expect(!mem.eql(u8, b_fmt, "(BigInt)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "(BigInt) negative" {
|
||||||
|
var a = try Managed.initSet(testing.allocator, 2);
|
||||||
|
defer a.deinit();
|
||||||
|
|
||||||
|
var b = try Managed.init(testing.allocator);
|
||||||
|
defer b.deinit();
|
||||||
|
|
||||||
|
var c = try Managed.initSet(testing.allocator, 1);
|
||||||
|
defer c.deinit();
|
||||||
|
|
||||||
|
// a = -pow(2, 64 * @sizeOf(usize) * 8), b = a + 1
|
||||||
|
try a.pow(&a, 64 * @sizeOf(Limb) * 8);
|
||||||
|
a.negate();
|
||||||
|
try b.add(&a, &c);
|
||||||
|
|
||||||
|
const a_fmt = try std.fmt.allocPrintZ(testing.allocator, "{d}", .{a});
|
||||||
|
defer testing.allocator.free(a_fmt);
|
||||||
|
|
||||||
|
const b_fmt = try std.fmt.allocPrintZ(testing.allocator, "{d}", .{b});
|
||||||
|
defer testing.allocator.free(b_fmt);
|
||||||
|
|
||||||
|
try testing.expect(mem.eql(u8, a_fmt, "(BigInt)"));
|
||||||
|
try testing.expect(!mem.eql(u8, b_fmt, "(BigInt)"));
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user