mirror of
https://github.com/ziglang/zig.git
synced 2026-02-18 15:31:48 +00:00
improve bit shift API in std.math
* `shl` moved to `shlExact` * added `shl` and `shr` which are truncating like `<<` and `>>`. closes #403
This commit is contained in:
parent
c6295fe9ab
commit
844e05f619
@ -219,11 +219,59 @@ pub fn negate(x: var) -> %@typeOf(x) {
|
||||
}
|
||||
|
||||
error Overflow;
|
||||
pub fn shl(comptime T: type, a: T, shift_amt: Log2Int(T)) -> %T {
|
||||
pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) -> %T {
|
||||
var answer: T = undefined;
|
||||
if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer
|
||||
}
|
||||
|
||||
/// Shifts left. Overflowed bits are truncated.
|
||||
/// A negative shift amount results in a right shift.
|
||||
pub fn shl(comptime T: type, a: T, shift_amt: var) -> T {
|
||||
const abs_shift_amt = absCast(shift_amt);
|
||||
const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);
|
||||
|
||||
if (@typeOf(shift_amt).is_signed) {
|
||||
if (shift_amt >= 0) {
|
||||
return a << casted_shift_amt;
|
||||
} else {
|
||||
return a >> casted_shift_amt;
|
||||
}
|
||||
}
|
||||
|
||||
return a << casted_shift_amt;
|
||||
}
|
||||
|
||||
test "math.shl" {
|
||||
assert(shl(u8, 0b11111111, usize(3)) == 0b11111000);
|
||||
assert(shl(u8, 0b11111111, usize(8)) == 0);
|
||||
assert(shl(u8, 0b11111111, usize(9)) == 0);
|
||||
assert(shl(u8, 0b11111111, isize(-2)) == 0b00111111);
|
||||
}
|
||||
|
||||
/// Shifts right. Overflowed bits are truncated.
|
||||
/// A negative shift amount results in a lefft shift.
|
||||
pub fn shr(comptime T: type, a: T, shift_amt: var) -> T {
|
||||
const abs_shift_amt = absCast(shift_amt);
|
||||
const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);
|
||||
|
||||
if (@typeOf(shift_amt).is_signed) {
|
||||
if (shift_amt >= 0) {
|
||||
return a >> casted_shift_amt;
|
||||
} else {
|
||||
return a << casted_shift_amt;
|
||||
}
|
||||
}
|
||||
|
||||
return a >> casted_shift_amt;
|
||||
}
|
||||
|
||||
test "math.shr" {
|
||||
assert(shr(u8, 0b11111111, usize(3)) == 0b00011111);
|
||||
assert(shr(u8, 0b11111111, usize(8)) == 0);
|
||||
assert(shr(u8, 0b11111111, usize(9)) == 0);
|
||||
assert(shr(u8, 0b11111111, isize(-2)) == 0b11111100);
|
||||
}
|
||||
|
||||
pub fn Log2Int(comptime T: type) -> type {
|
||||
@IntType(false, log2(T.bit_count))
|
||||
}
|
||||
@ -237,7 +285,7 @@ fn testOverflow() {
|
||||
assert(%%mul(i32, 3, 4) == 12);
|
||||
assert(%%add(i32, 3, 4) == 7);
|
||||
assert(%%sub(i32, 3, 4) == -1);
|
||||
assert(%%shl(i32, 0b11, 4) == 0b110000);
|
||||
assert(%%shlExact(i32, 0b11, 4) == 0b110000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user