diff options
| author | Robin Voetter <robin@voetter.nl> | 2021-09-26 07:40:40 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2021-10-04 11:25:29 +0200 |
| commit | a73369244471cf15ed8eda624e86c435a5df295f (patch) | |
| tree | f3141373dbf9aa9b90d998a3749a91864cb55a97 /src/value.zig | |
| parent | b58cf6dab6ff64c3403d3776a430694534f7b818 (diff) | |
| download | zig-a73369244471cf15ed8eda624e86c435a5df295f.tar.gz zig-a73369244471cf15ed8eda624e86c435a5df295f.zip | |
Update Value.intTrunc to use new big int truncate
Diffstat (limited to 'src/value.zig')
| -rw-r--r-- | src/value.zig | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/value.zig b/src/value.zig index 72fc46ef4c..fa11bb6ddb 100644 --- a/src/value.zig +++ b/src/value.zig @@ -2136,12 +2136,24 @@ pub const Value = extern union { } } - pub fn intTrunc(val: Value, arena: *Allocator, bits: u16) !Value { - const x = val.toUnsignedInt(); // TODO: implement comptime truncate on big ints - if (bits == 64) return val; - const mask = (@as(u64, 1) << @intCast(u6, bits)) - 1; - const truncated = x & mask; - return Tag.int_u64.create(arena, truncated); + pub fn intTrunc(val: Value, allocator: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Value { + var val_space: Value.BigIntSpace = undefined; + const val_bigint = val.toBigInt(&val_space); + + const limbs = try allocator.alloc( + std.math.big.Limb, + std.math.big.int.calcTwosCompLimbCount(bits), + ); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + result_bigint.truncate(val_bigint, signedness, bits); + const result_limbs = result_bigint.limbs[0..result_bigint.len]; + + if (result_bigint.positive) { + return Value.Tag.int_big_positive.create(allocator, result_limbs); + } else { + return Value.Tag.int_big_negative.create(allocator, result_limbs); + } } pub fn shl(lhs: Value, rhs: Value, allocator: *Allocator) !Value { |
