| ... | ... | @@ -109,3 +109,46 @@ test "comptime shr of BigInt" { |
| 109 | 109 | test "comptime shift safety check" { |
| 110 | 110 | _ = @as(usize, 42) << @sizeOf(usize); |
| 111 | 111 | } |
| 112 | |
| 113 | test "Saturating Shift Left where lhs is of a computed type" { |
| 114 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 115 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 116 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 117 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 118 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 119 | |
| 120 | const S = struct { |
| 121 | fn getIntShiftType(comptime T: type) type { |
| 122 | var unsigned_shift_type = @typeInfo(std.math.Log2Int(T)).Int; |
| 123 | unsigned_shift_type.signedness = .signed; |
| 124 | |
| 125 | return @Type(.{ |
| 126 | .Int = unsigned_shift_type, |
| 127 | }); |
| 128 | } |
| 129 | |
| 130 | pub fn FixedPoint(comptime value_type: type) type { |
| 131 | return struct { |
| 132 | value: value_type, |
| 133 | exponent: ShiftType, |
| 134 | |
| 135 | const ShiftType: type = getIntShiftType(value_type); |
| 136 | |
| 137 | pub fn shiftExponent(self: @This(), shift: ShiftType) @This() { |
| 138 | const shiftAbs = @abs(shift); |
| 139 | return .{ .value = if (shift >= 0) self.value >> shiftAbs else self.value <<| shiftAbs, .exponent = self.exponent + shift }; |
| 140 | } |
| 141 | }; |
| 142 | } |
| 143 | }; |
| 144 | |
| 145 | const FP = S.FixedPoint(i32); |
| 146 | |
| 147 | const value = (FP{ |
| 148 | .value = 1, |
| 149 | .exponent = 1, |
| 150 | }).shiftExponent(-1); |
| 151 | |
| 152 | try expect(value.value == 2); |
| 153 | try expect(value.exponent == 0); |
| 154 | } |