diff options
Diffstat (limited to 'lib/std/math.zig')
| -rw-r--r-- | lib/std/math.zig | 163 |
1 files changed, 83 insertions, 80 deletions
diff --git a/lib/std/math.zig b/lib/std/math.zig index 9b56d0b8ce..714521357c 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -10,6 +10,9 @@ pub const e = 2.71828182845904523536028747135266249775724709369995; /// Archimedes' constant (π) pub const pi = 3.14159265358979323846264338327950288419716939937510; +/// Circle constant (τ) +pub const tau = 2 * pi; + /// log2(e) pub const log2e = 1.442695040888963407359924681001892137; @@ -44,10 +47,10 @@ pub const sqrt2 = 1.414213562373095048801688724209698079; pub const sqrt1_2 = 0.707106781186547524400844362104849039; // From a small c++ [program using boost float128](https://github.com/winksaville/cpp_boost_float128) -pub const f128_true_min = @bitCast(f128, u128(0x00000000000000000000000000000001)); -pub const f128_min = @bitCast(f128, u128(0x00010000000000000000000000000000)); -pub const f128_max = @bitCast(f128, u128(0x7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); -pub const f128_epsilon = @bitCast(f128, u128(0x3F8F0000000000000000000000000000)); +pub const f128_true_min = @bitCast(f128, @as(u128, 0x00000000000000000000000000000001)); +pub const f128_min = @bitCast(f128, @as(u128, 0x00010000000000000000000000000000)); +pub const f128_max = @bitCast(f128, @as(u128, 0x7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); +pub const f128_epsilon = @bitCast(f128, @as(u128, 0x3F8F0000000000000000000000000000)); pub const f128_toint = 1.0 / f128_epsilon; // float.h details @@ -69,28 +72,28 @@ pub const f16_max = 65504; pub const f16_epsilon = 0.0009765625; // 2**-10 pub const f16_toint = 1.0 / f16_epsilon; -pub const nan_u16 = u16(0x7C01); +pub const nan_u16 = @as(u16, 0x7C01); pub const nan_f16 = @bitCast(f16, nan_u16); -pub const inf_u16 = u16(0x7C00); +pub const inf_u16 = @as(u16, 0x7C00); pub const inf_f16 = @bitCast(f16, inf_u16); -pub const nan_u32 = u32(0x7F800001); +pub const nan_u32 = @as(u32, 0x7F800001); pub const nan_f32 = @bitCast(f32, nan_u32); -pub const inf_u32 = u32(0x7F800000); +pub const inf_u32 = @as(u32, 0x7F800000); pub const inf_f32 = @bitCast(f32, inf_u32); -pub const nan_u64 = u64(0x7FF << 52) | 1; +pub const nan_u64 = @as(u64, 0x7FF << 52) | 1; pub const nan_f64 = @bitCast(f64, nan_u64); -pub const inf_u64 = u64(0x7FF << 52); +pub const inf_u64 = @as(u64, 0x7FF << 52); pub const inf_f64 = @bitCast(f64, inf_u64); -pub const nan_u128 = u128(0x7fff0000000000000000000000000001); +pub const nan_u128 = @as(u128, 0x7fff0000000000000000000000000001); pub const nan_f128 = @bitCast(f128, nan_u128); -pub const inf_u128 = u128(0x7fff0000000000000000000000000000); +pub const inf_u128 = @as(u128, 0x7fff0000000000000000000000000000); pub const inf_f128 = @bitCast(f128, inf_u128); pub const nan = @import("math/nan.zig").nan; @@ -248,7 +251,7 @@ pub fn Min(comptime A: type, comptime B: type) type { }, else => {}, } - return @typeOf(A(0) + B(0)); + return @typeOf(@as(A, 0) + @as(B, 0)); } /// Returns the smaller number. When one of the parameter's type's full range fits in the other, @@ -273,7 +276,7 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) { } test "math.min" { - testing.expect(min(i32(-1), i32(2)) == -1); + testing.expect(min(@as(i32, -1), @as(i32, 2)) == -1); { var a: u16 = 999; var b: u32 = 10; @@ -309,7 +312,7 @@ pub fn max(x: var, y: var) @typeOf(x + y) { } test "math.max" { - testing.expect(max(i32(-1), i32(2)) == 2); + testing.expect(max(@as(i32, -1), @as(i32, 2)) == 2); } pub fn mul(comptime T: type, a: T, b: T) (error{Overflow}!T) { @@ -352,10 +355,10 @@ pub fn shl(comptime T: type, a: T, shift_amt: var) T { } test "math.shl" { - testing.expect(shl(u8, 0b11111111, usize(3)) == 0b11111000); - testing.expect(shl(u8, 0b11111111, usize(8)) == 0); - testing.expect(shl(u8, 0b11111111, usize(9)) == 0); - testing.expect(shl(u8, 0b11111111, isize(-2)) == 0b00111111); + testing.expect(shl(u8, 0b11111111, @as(usize, 3)) == 0b11111000); + testing.expect(shl(u8, 0b11111111, @as(usize, 8)) == 0); + testing.expect(shl(u8, 0b11111111, @as(usize, 9)) == 0); + testing.expect(shl(u8, 0b11111111, @as(isize, -2)) == 0b00111111); testing.expect(shl(u8, 0b11111111, 3) == 0b11111000); testing.expect(shl(u8, 0b11111111, 8) == 0); testing.expect(shl(u8, 0b11111111, 9) == 0); @@ -380,10 +383,10 @@ pub fn shr(comptime T: type, a: T, shift_amt: var) T { } test "math.shr" { - testing.expect(shr(u8, 0b11111111, usize(3)) == 0b00011111); - testing.expect(shr(u8, 0b11111111, usize(8)) == 0); - testing.expect(shr(u8, 0b11111111, usize(9)) == 0); - testing.expect(shr(u8, 0b11111111, isize(-2)) == 0b11111100); + testing.expect(shr(u8, 0b11111111, @as(usize, 3)) == 0b00011111); + testing.expect(shr(u8, 0b11111111, @as(usize, 8)) == 0); + testing.expect(shr(u8, 0b11111111, @as(usize, 9)) == 0); + testing.expect(shr(u8, 0b11111111, @as(isize, -2)) == 0b11111100); testing.expect(shr(u8, 0b11111111, 3) == 0b00011111); testing.expect(shr(u8, 0b11111111, 8) == 0); testing.expect(shr(u8, 0b11111111, 9) == 0); @@ -402,11 +405,11 @@ pub fn rotr(comptime T: type, x: T, r: var) T { } test "math.rotr" { - testing.expect(rotr(u8, 0b00000001, usize(0)) == 0b00000001); - testing.expect(rotr(u8, 0b00000001, usize(9)) == 0b10000000); - testing.expect(rotr(u8, 0b00000001, usize(8)) == 0b00000001); - testing.expect(rotr(u8, 0b00000001, usize(4)) == 0b00010000); - testing.expect(rotr(u8, 0b00000001, isize(-1)) == 0b00000010); + testing.expect(rotr(u8, 0b00000001, @as(usize, 0)) == 0b00000001); + testing.expect(rotr(u8, 0b00000001, @as(usize, 9)) == 0b10000000); + testing.expect(rotr(u8, 0b00000001, @as(usize, 8)) == 0b00000001); + testing.expect(rotr(u8, 0b00000001, @as(usize, 4)) == 0b00010000); + testing.expect(rotr(u8, 0b00000001, @as(isize, -1)) == 0b00000010); } /// Rotates left. Only unsigned values can be rotated. @@ -421,11 +424,11 @@ pub fn rotl(comptime T: type, x: T, r: var) T { } test "math.rotl" { - testing.expect(rotl(u8, 0b00000001, usize(0)) == 0b00000001); - testing.expect(rotl(u8, 0b00000001, usize(9)) == 0b00000010); - testing.expect(rotl(u8, 0b00000001, usize(8)) == 0b00000001); - testing.expect(rotl(u8, 0b00000001, usize(4)) == 0b00010000); - testing.expect(rotl(u8, 0b00000001, isize(-1)) == 0b10000000); + testing.expect(rotl(u8, 0b00000001, @as(usize, 0)) == 0b00000001); + testing.expect(rotl(u8, 0b00000001, @as(usize, 9)) == 0b00000010); + testing.expect(rotl(u8, 0b00000001, @as(usize, 8)) == 0b00000001); + testing.expect(rotl(u8, 0b00000001, @as(usize, 4)) == 0b00010000); + testing.expect(rotl(u8, 0b00000001, @as(isize, -1)) == 0b10000000); } pub fn Log2Int(comptime T: type) type { @@ -532,8 +535,8 @@ test "math.absInt" { comptime testAbsInt(); } fn testAbsInt() void { - testing.expect((absInt(i32(-10)) catch unreachable) == 10); - testing.expect((absInt(i32(10)) catch unreachable) == 10); + testing.expect((absInt(@as(i32, -10)) catch unreachable) == 10); + testing.expect((absInt(@as(i32, 10)) catch unreachable) == 10); } pub const absFloat = fabs; @@ -543,8 +546,8 @@ test "math.absFloat" { comptime testAbsFloat(); } fn testAbsFloat() void { - testing.expect(absFloat(f32(-10.05)) == 10.05); - testing.expect(absFloat(f32(10.05)) == 10.05); + testing.expect(absFloat(@as(f32, -10.05)) == 10.05); + testing.expect(absFloat(@as(f32, 10.05)) == 10.05); } pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T { @@ -679,14 +682,14 @@ pub fn absCast(x: var) t: { } test "math.absCast" { - testing.expect(absCast(i32(-999)) == 999); - testing.expect(@typeOf(absCast(i32(-999))) == u32); + testing.expect(absCast(@as(i32, -999)) == 999); + testing.expect(@typeOf(absCast(@as(i32, -999))) == u32); - testing.expect(absCast(i32(999)) == 999); - testing.expect(@typeOf(absCast(i32(999))) == u32); + testing.expect(absCast(@as(i32, 999)) == 999); + testing.expect(@typeOf(absCast(@as(i32, 999))) == u32); - testing.expect(absCast(i32(minInt(i32))) == -minInt(i32)); - testing.expect(@typeOf(absCast(i32(minInt(i32)))) == u32); + testing.expect(absCast(@as(i32, minInt(i32))) == -minInt(i32)); + testing.expect(@typeOf(absCast(@as(i32, minInt(i32)))) == u32); testing.expect(absCast(-999) == 999); } @@ -705,13 +708,13 @@ pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) { } test "math.negateCast" { - testing.expect((negateCast(u32(999)) catch unreachable) == -999); - testing.expect(@typeOf(negateCast(u32(999)) catch unreachable) == i32); + testing.expect((negateCast(@as(u32, 999)) catch unreachable) == -999); + testing.expect(@typeOf(negateCast(@as(u32, 999)) catch unreachable) == i32); - testing.expect((negateCast(u32(-minInt(i32))) catch unreachable) == minInt(i32)); - testing.expect(@typeOf(negateCast(u32(-minInt(i32))) catch unreachable) == i32); + testing.expect((negateCast(@as(u32, -minInt(i32))) catch unreachable) == minInt(i32)); + testing.expect(@typeOf(negateCast(@as(u32, -minInt(i32))) catch unreachable) == i32); - testing.expectError(error.Overflow, negateCast(u32(maxInt(i32) + 10))); + testing.expectError(error.Overflow, negateCast(@as(u32, maxInt(i32) + 10))); } /// Cast an integer to a different integer type. If the value doesn't fit, @@ -729,13 +732,13 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) { } test "math.cast" { - testing.expectError(error.Overflow, cast(u8, u32(300))); - testing.expectError(error.Overflow, cast(i8, i32(-200))); - testing.expectError(error.Overflow, cast(u8, i8(-1))); - testing.expectError(error.Overflow, cast(u64, i8(-1))); + testing.expectError(error.Overflow, cast(u8, @as(u32, 300))); + testing.expectError(error.Overflow, cast(i8, @as(i32, -200))); + testing.expectError(error.Overflow, cast(u8, @as(i8, -1))); + testing.expectError(error.Overflow, cast(u64, @as(i8, -1))); - testing.expect((try cast(u8, u32(255))) == u8(255)); - testing.expect(@typeOf(try cast(u8, u32(255))) == u8); + testing.expect((try cast(u8, @as(u32, 255))) == @as(u8, 255)); + testing.expect(@typeOf(try cast(u8, @as(u32, 255))) == u8); } pub const AlignCastError = error{UnalignedMemory}; @@ -786,9 +789,9 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T comptime assert(@typeId(T) == builtin.TypeId.Int); comptime assert(!T.is_signed); assert(value != 0); - comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1); - comptime const shiftType = std.math.Log2Int(promotedType); - return promotedType(1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1)); + comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1); + comptime const shiftType = std.math.Log2Int(PromotedType); + return @as(PromotedType, 1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1)); } /// Returns the next power of two (if the value is not already a power of two). @@ -797,8 +800,8 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) { comptime assert(@typeId(T) == builtin.TypeId.Int); comptime assert(!T.is_signed); - comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1); - comptime const overflowBit = promotedType(1) << T.bit_count; + comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1); + comptime const overflowBit = @as(PromotedType, 1) << T.bit_count; var x = ceilPowerOfTwoPromote(T, value); if (overflowBit & x != 0) { return error.Overflow; @@ -812,15 +815,15 @@ test "math.ceilPowerOfTwoPromote" { } fn testCeilPowerOfTwoPromote() void { - testing.expectEqual(u33(1), ceilPowerOfTwoPromote(u32, 1)); - testing.expectEqual(u33(2), ceilPowerOfTwoPromote(u32, 2)); - testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 63)); - testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 64)); - testing.expectEqual(u33(128), ceilPowerOfTwoPromote(u32, 65)); - testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 7)); - testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 8)); - testing.expectEqual(u6(16), ceilPowerOfTwoPromote(u5, 9)); - testing.expectEqual(u5(16), ceilPowerOfTwoPromote(u4, 9)); + testing.expectEqual(@as(u33, 1), ceilPowerOfTwoPromote(u32, 1)); + testing.expectEqual(@as(u33, 2), ceilPowerOfTwoPromote(u32, 2)); + testing.expectEqual(@as(u33, 64), ceilPowerOfTwoPromote(u32, 63)); + testing.expectEqual(@as(u33, 64), ceilPowerOfTwoPromote(u32, 64)); + testing.expectEqual(@as(u33, 128), ceilPowerOfTwoPromote(u32, 65)); + testing.expectEqual(@as(u6, 8), ceilPowerOfTwoPromote(u5, 7)); + testing.expectEqual(@as(u6, 8), ceilPowerOfTwoPromote(u5, 8)); + testing.expectEqual(@as(u6, 16), ceilPowerOfTwoPromote(u5, 9)); + testing.expectEqual(@as(u5, 16), ceilPowerOfTwoPromote(u4, 9)); } test "math.ceilPowerOfTwo" { @@ -829,14 +832,14 @@ test "math.ceilPowerOfTwo" { } fn testCeilPowerOfTwo() !void { - testing.expectEqual(u32(1), try ceilPowerOfTwo(u32, 1)); - testing.expectEqual(u32(2), try ceilPowerOfTwo(u32, 2)); - testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 63)); - testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 64)); - testing.expectEqual(u32(128), try ceilPowerOfTwo(u32, 65)); - testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 7)); - testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 8)); - testing.expectEqual(u5(16), try ceilPowerOfTwo(u5, 9)); + testing.expectEqual(@as(u32, 1), try ceilPowerOfTwo(u32, 1)); + testing.expectEqual(@as(u32, 2), try ceilPowerOfTwo(u32, 2)); + testing.expectEqual(@as(u32, 64), try ceilPowerOfTwo(u32, 63)); + testing.expectEqual(@as(u32, 64), try ceilPowerOfTwo(u32, 64)); + testing.expectEqual(@as(u32, 128), try ceilPowerOfTwo(u32, 65)); + testing.expectEqual(@as(u5, 8), try ceilPowerOfTwo(u5, 7)); + testing.expectEqual(@as(u5, 8), try ceilPowerOfTwo(u5, 8)); + testing.expectEqual(@as(u5, 16), try ceilPowerOfTwo(u5, 9)); testing.expectError(error.Overflow, ceilPowerOfTwo(u4, 9)); } @@ -848,7 +851,7 @@ pub fn log2_int(comptime T: type, x: T) Log2Int(T) { pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) { assert(x != 0); const log2_val = log2_int(T, x); - if (T(1) << log2_val == x) + if (@as(T, 1) << log2_val == x) return log2_val; return log2_val + 1; } @@ -870,8 +873,8 @@ pub fn lossyCast(comptime T: type, value: var) T { switch (@typeInfo(@typeOf(value))) { builtin.TypeId.Int => return @intToFloat(T, value), builtin.TypeId.Float => return @floatCast(T, value), - builtin.TypeId.ComptimeInt => return T(value), - builtin.TypeId.ComptimeFloat => return T(value), + builtin.TypeId.ComptimeInt => return @as(T, value), + builtin.TypeId.ComptimeFloat => return @as(T, value), else => @compileError("bad type"), } } @@ -944,7 +947,7 @@ test "max value type" { pub fn mulWide(comptime T: type, a: T, b: T) @IntType(T.is_signed, T.bit_count * 2) { const ResultInt = @IntType(T.is_signed, T.bit_count * 2); - return ResultInt(a) * ResultInt(b); + return @as(ResultInt, a) * @as(ResultInt, b); } test "math.mulWide" { |
