authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2023-11-06 13:56:11-08:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-11-07 14:37:43+02:00
log03abac382457e071540314d050e21799b59b1d5b
treebc8e2c54c58260deae68122b1199e69a278a3ea5
parentb3462b7cec9931cd3747f10714954eb8efe00c04

fix sqrt(0)


2 files changed, 38 insertions(+), 1 deletions(-)

lib/std/math/big/int.zig+12-1
......@@ -3228,8 +3228,19 @@ pub const Managed = struct {
32283228
32293229 /// r = ⌊√a⌋
32303230 pub fn sqrt(rma: *Managed, a: *const Managed) !void {
3231 const needed_limbs = calcSqrtLimbsBufferLen(a.bitCountAbs());
3231 const bit_count = a.bitCountAbs();
32323232
3233 if (bit_count == 0) {
3234 try rma.set(0);
3235 rma.setMetadata(a.isPositive(), rma.len());
3236 return;
3237 }
3238
3239 if (!a.isPositive()) {
3240 return error.SqrtOfNegativeNumber;
3241 }
3242
3243 const needed_limbs = calcSqrtLimbsBufferLen(bit_count);
32333244 const limbs_buffer = try rma.allocator.alloc(Limb, needed_limbs);
32343245 defer rma.allocator.free(limbs_buffer);
32353246
lib/std/math/big/int_test.zig+26
......@@ -3149,3 +3149,29 @@ test "big.int.Const.order 0 == -0" {
31493149 };
31503150 try std.testing.expectEqual(std.math.Order.eq, a.order(b));
31513151}
3152
3153test "big.int.Managed sqrt(0) = 0" {
3154 const allocator = testing.allocator;
3155 var a = try Managed.initSet(allocator, 1);
3156 defer a.deinit();
3157
3158 var res = try Managed.initSet(allocator, 1);
3159 defer res.deinit();
3160
3161 try a.setString(10, "0");
3162
3163 try res.sqrt(&a);
3164}
3165
3166test "big.int.Managed sqrt(-1) = error" {
3167 const allocator = testing.allocator;
3168 var a = try Managed.initSet(allocator, 1);
3169 defer a.deinit();
3170
3171 var res = try Managed.initSet(allocator, 1);
3172 defer res.deinit();
3173
3174 try a.setString(10, "-1");
3175
3176 try testing.expectError(error.SqrtOfNegativeNumber, res.sqrt(&a));
3177}