| ... | @@ -267,6 +267,45 @@ test "math.shr" { | ... | @@ -267,6 +267,45 @@ test "math.shr" { |
| 267 | assert(shr(u8, 0b11111111, isize(-2)) == 0b11111100); | 267 | assert(shr(u8, 0b11111111, isize(-2)) == 0b11111100); |
| 268 | } | 268 | } |
| 269 | | 269 | |
| | 270 | /// Rotates right. Only unsigned values can be rotated. |
| | 271 | /// Negative shift values results in shift modulo the bit count. |
| | 272 | pub fn rotr(comptime T: type, x: T, r: var) -> T { |
| | 273 | if (T.is_signed) { |
| | 274 | @compileError("cannot rotate signed integer"); |
| | 275 | } else { |
| | 276 | const ar = @mod(r, T.bit_count); |
| | 277 | return shr(T, x, ar) | shl(T, x, T.bit_count - ar); |
| | 278 | } |
| | 279 | } |
| | 280 | |
| | 281 | test "math.rotr" { |
| | 282 | assert(rotr(u8, 0b00000001, usize(0)) == 0b00000001); |
| | 283 | assert(rotr(u8, 0b00000001, usize(9)) == 0b10000000); |
| | 284 | assert(rotr(u8, 0b00000001, usize(8)) == 0b00000001); |
| | 285 | assert(rotr(u8, 0b00000001, usize(4)) == 0b00010000); |
| | 286 | assert(rotr(u8, 0b00000001, isize(-1)) == 0b00000010); |
| | 287 | } |
| | 288 | |
| | 289 | /// Rotates left. Only unsigned values can be rotated. |
| | 290 | /// Negative shift values results in shift modulo the bit count. |
| | 291 | pub fn rotl(comptime T: type, x: T, r: var) -> T { |
| | 292 | if (T.is_signed) { |
| | 293 | @compileError("cannot rotate signed integer"); |
| | 294 | } else { |
| | 295 | const ar = @mod(r, T.bit_count); |
| | 296 | return shl(T, x, ar) | shr(T, x, T.bit_count - ar); |
| | 297 | } |
| | 298 | } |
| | 299 | |
| | 300 | test "math.rotl" { |
| | 301 | assert(rotl(u8, 0b00000001, usize(0)) == 0b00000001); |
| | 302 | assert(rotl(u8, 0b00000001, usize(9)) == 0b00000010); |
| | 303 | assert(rotl(u8, 0b00000001, usize(8)) == 0b00000001); |
| | 304 | assert(rotl(u8, 0b00000001, usize(4)) == 0b00010000); |
| | 305 | assert(rotl(u8, 0b00000001, isize(-1)) == 0b10000000); |
| | 306 | } |
| | 307 | |
| | 308 | |
| 270 | pub fn Log2Int(comptime T: type) -> type { | 309 | pub fn Log2Int(comptime T: type) -> type { |
| 271 | return @IntType(false, log2(T.bit_count)); | 310 | return @IntType(false, log2(T.bit_count)); |
| 272 | } | 311 | } |