| ... | ... | @@ -405,7 +405,14 @@ test "math.shr" { |
| 405 | 405 | /// Rotates right. Only unsigned values can be rotated. |
| 406 | 406 | /// Negative shift values results in shift modulo the bit count. |
| 407 | 407 | pub fn rotr(comptime T: type, x: T, r: anytype) T { |
| 408 | | if (@typeInfo(T).Int.is_signed) { |
| 408 | if (@typeInfo(T) == .Vector) { |
| 409 | const C = @typeInfo(T).Vector.child; |
| 410 | if (@typeInfo(C).Int.is_signed) { |
| 411 | @compileError("cannot rotate signed integers"); |
| 412 | } |
| 413 | const ar = @intCast(Log2Int(C), @mod(r, @typeInfo(C).Int.bits)); |
| 414 | return (x >> @splat(@typeInfo(T).Vector.len, ar)) | (x << @splat(@typeInfo(T).Vector.len, 1 + ~ar)); |
| 415 | } else if (@typeInfo(T).Int.is_signed) { |
| 409 | 416 | @compileError("cannot rotate signed integer"); |
| 410 | 417 | } else { |
| 411 | 418 | const ar = @mod(r, @typeInfo(T).Int.bits); |
| ... | ... | @@ -419,12 +426,21 @@ test "math.rotr" { |
| 419 | 426 | testing.expect(rotr(u8, 0b00000001, @as(usize, 8)) == 0b00000001); |
| 420 | 427 | testing.expect(rotr(u8, 0b00000001, @as(usize, 4)) == 0b00010000); |
| 421 | 428 | testing.expect(rotr(u8, 0b00000001, @as(isize, -1)) == 0b00000010); |
| 429 | testing.expect(rotr(std.meta.Vector(1, u32), std.meta.Vector(1, u32){1}, @as(usize, 1))[0] == @as(u32, 1) << 31); |
| 430 | testing.expect(rotr(std.meta.Vector(1, u32), std.meta.Vector(1, u32){1}, @as(isize, -1))[0] == @as(u32, 1) << 1); |
| 422 | 431 | } |
| 423 | 432 | |
| 424 | 433 | /// Rotates left. Only unsigned values can be rotated. |
| 425 | 434 | /// Negative shift values results in shift modulo the bit count. |
| 426 | 435 | pub fn rotl(comptime T: type, x: T, r: anytype) T { |
| 427 | | if (@typeInfo(T).Int.is_signed) { |
| 436 | if (@typeInfo(T) == .Vector) { |
| 437 | const C = @typeInfo(T).Vector.child; |
| 438 | if (@typeInfo(C).Int.is_signed) { |
| 439 | @compileError("cannot rotate signed integers"); |
| 440 | } |
| 441 | const ar = @intCast(Log2Int(C), @mod(r, @typeInfo(C).Int.bits)); |
| 442 | return (x << @splat(@typeInfo(T).Vector.len, ar)) | (x >> @splat(@typeInfo(T).Vector.len, 1 +% ~ar)); |
| 443 | } else if (@typeInfo(T).Int.is_signed) { |
| 428 | 444 | @compileError("cannot rotate signed integer"); |
| 429 | 445 | } else { |
| 430 | 446 | const ar = @mod(r, @typeInfo(T).Int.bits); |
| ... | ... | @@ -438,6 +454,8 @@ test "math.rotl" { |
| 438 | 454 | testing.expect(rotl(u8, 0b00000001, @as(usize, 8)) == 0b00000001); |
| 439 | 455 | testing.expect(rotl(u8, 0b00000001, @as(usize, 4)) == 0b00010000); |
| 440 | 456 | testing.expect(rotl(u8, 0b00000001, @as(isize, -1)) == 0b10000000); |
| 457 | testing.expect(rotl(std.meta.Vector(1, u32), std.meta.Vector(1, u32){1 << 31}, @as(usize, 1))[0] == 1); |
| 458 | testing.expect(rotl(std.meta.Vector(1, u32), std.meta.Vector(1, u32){1 << 31}, @as(isize, -1))[0] == @as(u32, 1) << 30); |
| 441 | 459 | } |
| 442 | 460 | |
| 443 | 461 | pub fn Log2Int(comptime T: type) type { |
| ... | ... | @@ -1141,4 +1159,3 @@ test "math.comptime" { |
| 1141 | 1159 | comptime const v = sin(@as(f32, 1)) + ln(@as(f32, 5)); |
| 1142 | 1160 | testing.expect(v == sin(@as(f32, 1)) + ln(@as(f32, 5))); |
| 1143 | 1161 | } |
| 1144 | | |