| ... | @@ -18,18 +18,12 @@ const debug_safety = false; | ... | @@ -18,18 +18,12 @@ const debug_safety = false; |
| 18 | /// Returns the number of limbs needed to store `scalar`, which must be a | 18 | /// Returns the number of limbs needed to store `scalar`, which must be a |
| 19 | /// primitive integer value. | 19 | /// primitive integer value. |
| 20 | pub fn calcLimbLen(scalar: anytype) usize { | 20 | pub fn calcLimbLen(scalar: anytype) usize { |
| 21 | const T = @TypeOf(scalar); | 21 | if (scalar == 0) { |
| 22 | switch (@typeInfo(T)) { | 22 | return 1; |
| 23 | .Int => |info| { | | |
| 24 | const UT = if (info.signedness == .signed) std.meta.Int(.unsigned, info.bits - 1) else T; | | |
| 25 | return @sizeOf(UT) / @sizeOf(Limb); | | |
| 26 | }, | | |
| 27 | .ComptimeInt => { | | |
| 28 | const w_value = if (scalar < 0) -scalar else scalar; | | |
| 29 | return @divFloor(math.log2(w_value), limb_bits) + 1; | | |
| 30 | }, | | |
| 31 | else => @compileError("parameter must be a primitive integer type"), | | |
| 32 | } | 23 | } |
| | 24 | |
| | 25 | const w_value = std.math.absCast(scalar); |
| | 26 | return @divFloor(@intCast(Limb, math.log2(w_value)), limb_bits) + 1; |
| 33 | } | 27 | } |
| 34 | | 28 | |
| 35 | pub fn calcToStringLimbsBufferLen(a_len: usize, base: u8) usize { | 29 | pub fn calcToStringLimbsBufferLen(a_len: usize, base: u8) usize { |
| ... | @@ -218,26 +212,22 @@ pub const Mutable = struct { | ... | @@ -218,26 +212,22 @@ pub const Mutable = struct { |
| 218 | /// needs to be to store a specific value. | 212 | /// needs to be to store a specific value. |
| 219 | pub fn set(self: *Mutable, value: anytype) void { | 213 | pub fn set(self: *Mutable, value: anytype) void { |
| 220 | const T = @TypeOf(value); | 214 | const T = @TypeOf(value); |
| | 215 | const needed_limbs = calcLimbLen(value); |
| | 216 | assert(needed_limbs <= self.limbs.len); // value too big |
| | 217 | |
| | 218 | self.len = needed_limbs; |
| | 219 | self.positive = value >= 0; |
| 221 | | 220 | |
| 222 | switch (@typeInfo(T)) { | 221 | switch (@typeInfo(T)) { |
| 223 | .Int => |info| { | 222 | .Int => |info| { |
| 224 | const UT = if (info.signedness == .signed) std.meta.Int(.unsigned, info.bits - 1) else T; | 223 | var w_value = std.math.absCast(value); |
| 225 | | | |
| 226 | const needed_limbs = @sizeOf(UT) / @sizeOf(Limb); | | |
| 227 | assert(needed_limbs <= self.limbs.len); // value too big | | |
| 228 | self.len = 0; | | |
| 229 | self.positive = value >= 0; | | |
| 230 | | | |
| 231 | var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value); | | |
| 232 | | 224 | |
| 233 | if (info.bits <= limb_bits) { | 225 | if (info.bits <= limb_bits) { |
| 234 | self.limbs[0] = @as(Limb, w_value); | 226 | self.limbs[0] = w_value; |
| 235 | self.len += 1; | | |
| 236 | } else { | 227 | } else { |
| 237 | var i: usize = 0; | 228 | var i: usize = 0; |
| 238 | while (w_value != 0) : (i += 1) { | 229 | while (w_value != 0) : (i += 1) { |
| 239 | self.limbs[i] = @truncate(Limb, w_value); | 230 | self.limbs[i] = @truncate(Limb, w_value); |
| 240 | self.len += 1; | | |
| 241 | | 231 | |
| 242 | // TODO: shift == 64 at compile-time fails. Fails on u128 limbs. | 232 | // TODO: shift == 64 at compile-time fails. Fails on u128 limbs. |
| 243 | w_value >>= limb_bits / 2; | 233 | w_value >>= limb_bits / 2; |
| ... | @@ -246,13 +236,7 @@ pub const Mutable = struct { | ... | @@ -246,13 +236,7 @@ pub const Mutable = struct { |
| 246 | } | 236 | } |
| 247 | }, | 237 | }, |
| 248 | .ComptimeInt => { | 238 | .ComptimeInt => { |
| 249 | comptime var w_value = if (value < 0) -value else value; | 239 | comptime var w_value = std.math.absCast(value); |
| 250 | | | |
| 251 | const req_limbs = @divFloor(math.log2(w_value), limb_bits) + 1; | | |
| 252 | assert(req_limbs <= self.limbs.len); // value too big | | |
| 253 | | | |
| 254 | self.len = req_limbs; | | |
| 255 | self.positive = value >= 0; | | |
| 256 | | 240 | |
| 257 | if (w_value <= maxInt(Limb)) { | 241 | if (w_value <= maxInt(Limb)) { |
| 258 | self.limbs[0] = w_value; | 242 | self.limbs[0] = w_value; |