| author | |
| committer | |
| log | bcf4a1391331e52e4a06528530316970ded75c74 |
| tree | 484d6472f552780d6482b8457e56b29f9a06379d |
| parent | 1c02e58fc06aa3e429f963e600e126611df3626e |
Replaces occurences of @fabs absCast and absInt with new @abs builtin.
Also removes the std.math.fabs alias from math.zig.21 files changed, 92 insertions(+), 136 deletions(-)
lib/compiler_rt/divc3.zig+1-2| ... | @@ -3,7 +3,6 @@ const isNan = std.math.isNan; | ... | @@ -3,7 +3,6 @@ const isNan = std.math.isNan; |
| 3 | const isInf = std.math.isInf; | 3 | const isInf = std.math.isInf; |
| 4 | const scalbn = std.math.scalbn; | 4 | const scalbn = std.math.scalbn; |
| 5 | const ilogb = std.math.ilogb; | 5 | const ilogb = std.math.ilogb; |
| 6 | const fabs = std.math.fabs; | ||
| 7 | const maxInt = std.math.maxInt; | 6 | const maxInt = std.math.maxInt; |
| 8 | const minInt = std.math.minInt; | 7 | const minInt = std.math.minInt; |
| 9 | const isFinite = std.math.isFinite; | 8 | const isFinite = std.math.isFinite; |
| ... | @@ -16,7 +15,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { | ... | @@ -16,7 +15,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { |
| 16 | var d = d_in; | 15 | var d = d_in; |
| 17 | 16 | ||
| 18 | // logbw used to prevent under/over-flow | 17 | // logbw used to prevent under/over-flow |
| 19 | const logbw = ilogb(@max(fabs(c), fabs(d))); | 18 | const logbw = ilogb(@max(@abs(c), @abs(d))); |
| 20 | const logbw_finite = logbw != maxInt(i32) and logbw != minInt(i32); | 19 | const logbw_finite = logbw != maxInt(i32) and logbw != minInt(i32); |
| 21 | const ilogbw = if (logbw_finite) b: { | 20 | const ilogbw = if (logbw_finite) b: { |
| 22 | c = scalbn(c, -logbw); | 21 | c = scalbn(c, -logbw); |
lib/compiler_rt/divxf3_test.zig+3-3| ... | @@ -30,9 +30,9 @@ fn test__divxf3(a: f80, b: f80) !void { | ... | @@ -30,9 +30,9 @@ fn test__divxf3(a: f80, b: f80) !void { |
| 30 | const x_minus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) - 1) | integerBit); | 30 | const x_minus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) - 1) | integerBit); |
| 31 | 31 | ||
| 32 | // Make sure result is more accurate than the adjacent floats | 32 | // Make sure result is more accurate than the adjacent floats |
| 33 | const err_x = @fabs(@mulAdd(f80, x, b, -a)); | 33 | const err_x = @abs(@mulAdd(f80, x, b, -a)); |
| 34 | const err_x_plus_eps = @fabs(@mulAdd(f80, x_plus_eps, b, -a)); | 34 | const err_x_plus_eps = @abs(@mulAdd(f80, x_plus_eps, b, -a)); |
| 35 | const err_x_minus_eps = @fabs(@mulAdd(f80, x_minus_eps, b, -a)); | 35 | const err_x_minus_eps = @abs(@mulAdd(f80, x_minus_eps, b, -a)); |
| 36 | 36 | ||
| 37 | try testing.expect(err_x_minus_eps > err_x); | 37 | try testing.expect(err_x_minus_eps > err_x); |
| 38 | try testing.expect(err_x_plus_eps > err_x); | 38 | try testing.expect(err_x_plus_eps > err_x); |
lib/compiler_rt/float_from_int.zig+1-1| ... | @@ -18,7 +18,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T { | ... | @@ -18,7 +18,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T { |
| 18 | const max_exp = exp_bias; | 18 | const max_exp = exp_bias; |
| 19 | 19 | ||
| 20 | // Sign | 20 | // Sign |
| 21 | var abs_val = math.absCast(x); | 21 | var abs_val = if (@TypeOf(x) == comptime_int or @typeInfo(@TypeOf(x)).Int.signedness == .signed) @abs(x) else x; |
| 22 | const sign_bit = if (x < 0) @as(uT, 1) << (float_bits - 1) else 0; | 22 | const sign_bit = if (x < 0) @as(uT, 1) << (float_bits - 1) else 0; |
| 23 | var result: uT = sign_bit; | 23 | var result: uT = sign_bit; |
| 24 | 24 |
lib/std/Build/Step/ConfigHeader.zig+1-1| ... | @@ -539,7 +539,7 @@ fn replace_variables( | ... | @@ -539,7 +539,7 @@ fn replace_variables( |
| 539 | .int => |i| { | 539 | .int => |i| { |
| 540 | const buf = try std.fmt.allocPrint(allocator, "{s}{}{s}", .{ beginline, i, endline }); | 540 | const buf = try std.fmt.allocPrint(allocator, "{s}{}{s}", .{ beginline, i, endline }); |
| 541 | const isNegative = i < 0; | 541 | const isNegative = i < 0; |
| 542 | const digits = (if (0 < i) std.math.log10(std.math.absCast(i)) else 0) + 1; | 542 | const digits = (if (0 < i) std.math.log10(@abs(i)) else 0) + 1; |
| 543 | last_index = start_index + @intFromBool(isNegative) + digits + 1; | 543 | last_index = start_index + @intFromBool(isNegative) + digits + 1; |
| 544 | 544 | ||
| 545 | allocator.free(content_buf); | 545 | allocator.free(content_buf); |
lib/std/dwarf/expressions.zig+1-1| ... | @@ -520,7 +520,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { | ... | @@ -520,7 +520,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { |
| 520 | if (self.stack.items.len == 0) return error.InvalidExpression; | 520 | if (self.stack.items.len == 0) return error.InvalidExpression; |
| 521 | const value: isize = @bitCast(try self.stack.items[self.stack.items.len - 1].asIntegral()); | 521 | const value: isize = @bitCast(try self.stack.items[self.stack.items.len - 1].asIntegral()); |
| 522 | self.stack.items[self.stack.items.len - 1] = .{ | 522 | self.stack.items[self.stack.items.len - 1] = .{ |
| 523 | .generic = std.math.absCast(value), | 523 | .generic = @abs(value), |
| 524 | }; | 524 | }; |
| 525 | }, | 525 | }, |
| 526 | OP.@"and" => { | 526 | OP.@"and" => { |
lib/std/fmt.zig+1-1| ... | @@ -1413,7 +1413,7 @@ pub fn formatInt( | ... | @@ -1413,7 +1413,7 @@ pub fn formatInt( |
| 1413 | const min_int_bits = comptime @max(value_info.bits, 8); | 1413 | const min_int_bits = comptime @max(value_info.bits, 8); |
| 1414 | const MinInt = std.meta.Int(.unsigned, min_int_bits); | 1414 | const MinInt = std.meta.Int(.unsigned, min_int_bits); |
| 1415 | 1415 | ||
| 1416 | const abs_value = math.absCast(int_value); | 1416 | const abs_value = @abs(int_value); |
| 1417 | // The worst case in terms of space needed is base 2, plus 1 for the sign | 1417 | // The worst case in terms of space needed is base 2, plus 1 for the sign |
| 1418 | var buf: [1 + @max(@as(comptime_int, value_info.bits), 1)]u8 = undefined; | 1418 | var buf: [1 + @max(@as(comptime_int, value_info.bits), 1)]u8 = undefined; |
| 1419 | 1419 |
lib/std/io/fixed_buffer_stream.zig+1-1| ... | @@ -81,7 +81,7 @@ pub fn FixedBufferStream(comptime Buffer: type) type { | ... | @@ -81,7 +81,7 @@ pub fn FixedBufferStream(comptime Buffer: type) type { |
| 81 | 81 | ||
| 82 | pub fn seekBy(self: *Self, amt: i64) SeekError!void { | 82 | pub fn seekBy(self: *Self, amt: i64) SeekError!void { |
| 83 | if (amt < 0) { | 83 | if (amt < 0) { |
| 84 | const abs_amt = std.math.absCast(amt); | 84 | const abs_amt = @abs(amt); |
| 85 | const abs_amt_usize = std.math.cast(usize, abs_amt) orelse std.math.maxInt(usize); | 85 | const abs_amt_usize = std.math.cast(usize, abs_amt) orelse std.math.maxInt(usize); |
| 86 | if (abs_amt_usize > self.pos) { | 86 | if (abs_amt_usize > self.pos) { |
| 87 | self.pos = 0; | 87 | self.pos = 0; |
lib/std/math.zig+4-94| ... | @@ -130,7 +130,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { | ... | @@ -130,7 +130,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { |
| 130 | if (isNan(x) or isNan(y)) | 130 | if (isNan(x) or isNan(y)) |
| 131 | return false; | 131 | return false; |
| 132 | 132 | ||
| 133 | return @fabs(x - y) <= tolerance; | 133 | return @abs(x - y) <= tolerance; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | /// Performs an approximate comparison of two floating point values `x` and `y`. | 136 | /// Performs an approximate comparison of two floating point values `x` and `y`. |
| ... | @@ -158,7 +158,7 @@ pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool { | ... | @@ -158,7 +158,7 @@ pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool { |
| 158 | if (isNan(x) or isNan(y)) | 158 | if (isNan(x) or isNan(y)) |
| 159 | return false; | 159 | return false; |
| 160 | 160 | ||
| 161 | return @fabs(x - y) <= @max(@fabs(x), @fabs(y)) * tolerance; | 161 | return @abs(x - y) <= @max(@abs(x), @abs(y)) * tolerance; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | test "approxEqAbs and approxEqRel" { | 164 | test "approxEqAbs and approxEqRel" { |
| ... | @@ -466,7 +466,7 @@ pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) !T { | ... | @@ -466,7 +466,7 @@ pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) !T { |
| 466 | /// Shifts left. Overflowed bits are truncated. | 466 | /// Shifts left. Overflowed bits are truncated. |
| 467 | /// A negative shift amount results in a right shift. | 467 | /// A negative shift amount results in a right shift. |
| 468 | pub fn shl(comptime T: type, a: T, shift_amt: anytype) T { | 468 | pub fn shl(comptime T: type, a: T, shift_amt: anytype) T { |
| 469 | const abs_shift_amt = absCast(shift_amt); | 469 | const abs_shift_amt = @abs(shift_amt); |
| 470 | 470 | ||
| 471 | const casted_shift_amt = blk: { | 471 | const casted_shift_amt = blk: { |
| 472 | if (@typeInfo(T) == .Vector) { | 472 | if (@typeInfo(T) == .Vector) { |
| ... | @@ -510,7 +510,7 @@ test "shl" { | ... | @@ -510,7 +510,7 @@ test "shl" { |
| 510 | /// Shifts right. Overflowed bits are truncated. | 510 | /// Shifts right. Overflowed bits are truncated. |
| 511 | /// A negative shift amount results in a left shift. | 511 | /// A negative shift amount results in a left shift. |
| 512 | pub fn shr(comptime T: type, a: T, shift_amt: anytype) T { | 512 | pub fn shr(comptime T: type, a: T, shift_amt: anytype) T { |
| 513 | const abs_shift_amt = absCast(shift_amt); | 513 | const abs_shift_amt = @abs(shift_amt); |
| 514 | 514 | ||
| 515 | const casted_shift_amt = blk: { | 515 | const casted_shift_amt = blk: { |
| 516 | if (@typeInfo(T) == .Vector) { | 516 | if (@typeInfo(T) == .Vector) { |
| ... | @@ -740,52 +740,6 @@ fn testOverflow() !void { | ... | @@ -740,52 +740,6 @@ fn testOverflow() !void { |
| 740 | try testing.expect((shlExact(i32, 0b11, 4) catch unreachable) == 0b110000); | 740 | try testing.expect((shlExact(i32, 0b11, 4) catch unreachable) == 0b110000); |
| 741 | } | 741 | } |
| 742 | 742 | ||
| 743 | /// Returns the absolute value of x, where x is a value of a signed integer type. | ||
| 744 | /// Does not convert and returns a value of a signed integer type. | ||
| 745 | /// Use `absCast` if you want to convert the result and get an unsigned type. | ||
| 746 | /// Use `@fabs` if you need the absolute value of a floating point value. | ||
| 747 | pub fn absInt(x: anytype) !@TypeOf(x) { | ||
| 748 | const T = @TypeOf(x); | ||
| 749 | return switch (@typeInfo(T)) { | ||
| 750 | .Int => |info| { | ||
| 751 | comptime assert(info.signedness == .signed); // must pass a signed integer to absInt | ||
| 752 | if (x == minInt(T)) { | ||
| 753 | return error.Overflow; | ||
| 754 | } else { | ||
| 755 | @setRuntimeSafety(false); | ||
| 756 | return if (x < 0) -x else x; | ||
| 757 | } | ||
| 758 | }, | ||
| 759 | .Vector => |vinfo| blk: { | ||
| 760 | switch (@typeInfo(vinfo.child)) { | ||
| 761 | .Int => |info| { | ||
| 762 | comptime assert(info.signedness == .signed); // must pass a signed integer to absInt | ||
| 763 | if (@reduce(.Or, x == @as(T, @splat(minInt(vinfo.child))))) { | ||
| 764 | return error.Overflow; | ||
| 765 | } | ||
| 766 | const zero: T = @splat(0); | ||
| 767 | break :blk @select(vinfo.child, x > zero, x, -x); | ||
| 768 | }, | ||
| 769 | else => @compileError("Expected vector of ints, found " ++ @typeName(T)), | ||
| 770 | } | ||
| 771 | }, | ||
| 772 | else => @compileError("Expected an int or vector, found " ++ @typeName(T)), | ||
| 773 | }; | ||
| 774 | } | ||
| 775 | |||
| 776 | test "absInt" { | ||
| 777 | try testAbsInt(); | ||
| 778 | try comptime testAbsInt(); | ||
| 779 | } | ||
| 780 | fn testAbsInt() !void { | ||
| 781 | try testing.expect((absInt(@as(i32, -10)) catch unreachable) == 10); | ||
| 782 | try testing.expect((absInt(@as(i32, 10)) catch unreachable) == 10); | ||
| 783 | try testing.expectEqual(@Vector(3, i32){ 10, 10, 0 }, (absInt(@Vector(3, i32){ -10, 10, 0 }) catch unreachable)); | ||
| 784 | |||
| 785 | try testing.expectError(error.Overflow, absInt(@as(i32, minInt(i32)))); | ||
| 786 | try testing.expectError(error.Overflow, absInt(@Vector(3, i32){ 10, -10, minInt(i32) })); | ||
| 787 | } | ||
| 788 | |||
| 789 | /// Divide numerator by denominator, rounding toward zero. Returns an | 743 | /// Divide numerator by denominator, rounding toward zero. Returns an |
| 790 | /// error on overflow or when denominator is zero. | 744 | /// error on overflow or when denominator is zero. |
| 791 | pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T { | 745 | pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T { |
| ... | @@ -968,50 +922,6 @@ fn testRem() !void { | ... | @@ -968,50 +922,6 @@ fn testRem() !void { |
| 968 | try testing.expectError(error.DivisionByZero, rem(f32, 10, 0)); | 922 | try testing.expectError(error.DivisionByZero, rem(f32, 10, 0)); |
| 969 | } | 923 | } |
| 970 | 924 | ||
| 971 | /// Returns the absolute value of a floating point number. | ||
| 972 | /// Uses a dedicated hardware instruction when available. | ||
| 973 | /// This is the same as calling the builtin @fabs | ||
| 974 | pub inline fn fabs(value: anytype) @TypeOf(value) { | ||
| 975 | return @fabs(value); | ||
| 976 | } | ||
| 977 | |||
| 978 | /// Returns the absolute value of the integer parameter. | ||
| 979 | /// Converts result type to unsigned if needed and returns a value of an unsigned integer type. | ||
| 980 | /// Use `absInt` if you want to keep your integer type signed. | ||
| 981 | pub fn absCast(x: anytype) switch (@typeInfo(@TypeOf(x))) { | ||
| 982 | .ComptimeInt => comptime_int, | ||
| 983 | .Int => |int_info| std.meta.Int(.unsigned, int_info.bits), | ||
| 984 | else => @compileError("absCast only accepts integers"), | ||
| 985 | } { | ||
| 986 | switch (@typeInfo(@TypeOf(x))) { | ||
| 987 | .ComptimeInt => { | ||
| 988 | if (x < 0) { | ||
| 989 | return -x; | ||
| 990 | } else { | ||
| 991 | return x; | ||
| 992 | } | ||
| 993 | }, | ||
| 994 | .Int => |int_info| { | ||
| 995 | if (int_info.signedness == .unsigned) return x; | ||
| 996 | const Uint = std.meta.Int(.unsigned, int_info.bits); | ||
| 997 | if (x < 0) { | ||
| 998 | return ~@as(Uint, @bitCast(x +% -1)); | ||
| 999 | } else { | ||
| 1000 | return @as(Uint, @intCast(x)); | ||
| 1001 | } | ||
| 1002 | }, | ||
| 1003 | else => unreachable, | ||
| 1004 | } | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | test "absCast" { | ||
| 1008 | try testing.expectEqual(@as(u1, 1), absCast(@as(i1, -1))); | ||
| 1009 | try testing.expectEqual(@as(u32, 999), absCast(@as(i32, -999))); | ||
| 1010 | try testing.expectEqual(@as(u32, 999), absCast(@as(i32, 999))); | ||
| 1011 | try testing.expectEqual(@as(u32, -minInt(i32)), absCast(@as(i32, minInt(i32)))); | ||
| 1012 | try testing.expectEqual(999, absCast(-999)); | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | /// Returns the negation of the integer parameter. | 925 | /// Returns the negation of the integer parameter. |
| 1016 | /// Result is a signed integer. | 926 | /// Result is a signed integer. |
| 1017 | pub fn negateCast(x: anytype) !std.meta.Int(.signed, @bitSizeOf(@TypeOf(x))) { | 927 | pub fn negateCast(x: anytype) !std.meta.Int(.signed, @bitSizeOf(@TypeOf(x))) { |
lib/std/math/asin.zig+2-2| ... | @@ -60,7 +60,7 @@ fn asin32(x: f32) f32 { | ... | @@ -60,7 +60,7 @@ fn asin32(x: f32) f32 { |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | // 1 > |x| >= 0.5 | 62 | // 1 > |x| >= 0.5 |
| 63 | const z = (1 - @fabs(x)) * 0.5; | 63 | const z = (1 - @abs(x)) * 0.5; |
| 64 | const s = @sqrt(z); | 64 | const s = @sqrt(z); |
| 65 | const fx = pio2 - 2 * (s + s * r32(z)); | 65 | const fx = pio2 - 2 * (s + s * r32(z)); |
| 66 | 66 | ||
| ... | @@ -119,7 +119,7 @@ fn asin64(x: f64) f64 { | ... | @@ -119,7 +119,7 @@ fn asin64(x: f64) f64 { |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | // 1 > |x| >= 0.5 | 121 | // 1 > |x| >= 0.5 |
| 122 | const z = (1 - @fabs(x)) * 0.5; | 122 | const z = (1 - @abs(x)) * 0.5; |
| 123 | const s = @sqrt(z); | 123 | const s = @sqrt(z); |
| 124 | const r = r64(z); | 124 | const r = r64(z); |
| 125 | var fx: f64 = undefined; | 125 | var fx: f64 = undefined; |
lib/std/math/atan.zig+2-2| ... | @@ -73,7 +73,7 @@ fn atan32(x_: f32) f32 { | ... | @@ -73,7 +73,7 @@ fn atan32(x_: f32) f32 { |
| 73 | } | 73 | } |
| 74 | id = null; | 74 | id = null; |
| 75 | } else { | 75 | } else { |
| 76 | x = @fabs(x); | 76 | x = @abs(x); |
| 77 | // |x| < 1.1875 | 77 | // |x| < 1.1875 |
| 78 | if (ix < 0x3F980000) { | 78 | if (ix < 0x3F980000) { |
| 79 | // 7/16 <= |x| < 11/16 | 79 | // 7/16 <= |x| < 11/16 |
| ... | @@ -171,7 +171,7 @@ fn atan64(x_: f64) f64 { | ... | @@ -171,7 +171,7 @@ fn atan64(x_: f64) f64 { |
| 171 | } | 171 | } |
| 172 | id = null; | 172 | id = null; |
| 173 | } else { | 173 | } else { |
| 174 | x = @fabs(x); | 174 | x = @abs(x); |
| 175 | // |x| < 1.1875 | 175 | // |x| < 1.1875 |
| 176 | if (ix < 0x3FF30000) { | 176 | if (ix < 0x3FF30000) { |
| 177 | // 7/16 <= |x| < 11/16 | 177 | // 7/16 <= |x| < 11/16 |
lib/std/math/atan2.zig+2-2| ... | @@ -108,7 +108,7 @@ fn atan2_32(y: f32, x: f32) f32 { | ... | @@ -108,7 +108,7 @@ fn atan2_32(y: f32, x: f32) f32 { |
| 108 | if ((m & 2) != 0 and iy + (26 << 23) < ix) { | 108 | if ((m & 2) != 0 and iy + (26 << 23) < ix) { |
| 109 | break :z 0.0; | 109 | break :z 0.0; |
| 110 | } else { | 110 | } else { |
| 111 | break :z math.atan(@fabs(y / x)); | 111 | break :z math.atan(@abs(y / x)); |
| 112 | } | 112 | } |
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| ... | @@ -198,7 +198,7 @@ fn atan2_64(y: f64, x: f64) f64 { | ... | @@ -198,7 +198,7 @@ fn atan2_64(y: f64, x: f64) f64 { |
| 198 | if ((m & 2) != 0 and iy +% (64 << 20) < ix) { | 198 | if ((m & 2) != 0 and iy +% (64 << 20) < ix) { |
| 199 | break :z 0.0; | 199 | break :z 0.0; |
| 200 | } else { | 200 | } else { |
| 201 | break :z math.atan(@fabs(y / x)); | 201 | break :z math.atan(@abs(y / x)); |
| 202 | } | 202 | } |
| 203 | }; | 203 | }; |
| 204 | 204 |
lib/std/math/big/int.zig+3-3| ... | @@ -29,7 +29,7 @@ pub fn calcLimbLen(scalar: anytype) usize { | ... | @@ -29,7 +29,7 @@ pub fn calcLimbLen(scalar: anytype) usize { |
| 29 | return 1; | 29 | return 1; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | const w_value = std.math.absCast(scalar); | 32 | const w_value = @abs(scalar); |
| 33 | return @as(usize, @intCast(@divFloor(@as(Limb, @intCast(math.log2(w_value))), limb_bits) + 1)); | 33 | return @as(usize, @intCast(@divFloor(@as(Limb, @intCast(math.log2(w_value))), limb_bits) + 1)); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| ... | @@ -240,7 +240,7 @@ pub const Mutable = struct { | ... | @@ -240,7 +240,7 @@ pub const Mutable = struct { |
| 240 | 240 | ||
| 241 | switch (@typeInfo(T)) { | 241 | switch (@typeInfo(T)) { |
| 242 | .Int => |info| { | 242 | .Int => |info| { |
| 243 | var w_value = std.math.absCast(value); | 243 | var w_value = @abs(value); |
| 244 | 244 | ||
| 245 | if (info.bits <= limb_bits) { | 245 | if (info.bits <= limb_bits) { |
| 246 | self.limbs[0] = w_value; | 246 | self.limbs[0] = w_value; |
| ... | @@ -255,7 +255,7 @@ pub const Mutable = struct { | ... | @@ -255,7 +255,7 @@ pub const Mutable = struct { |
| 255 | } | 255 | } |
| 256 | }, | 256 | }, |
| 257 | .ComptimeInt => { | 257 | .ComptimeInt => { |
| 258 | comptime var w_value = std.math.absCast(value); | 258 | comptime var w_value = @abs(value); |
| 259 | 259 | ||
| 260 | if (w_value <= maxInt(Limb)) { | 260 | if (w_value <= maxInt(Limb)) { |
| 261 | self.limbs[0] = w_value; | 261 | self.limbs[0] = w_value; |
lib/std/math/complex/cosh.zig+4-4| ... | @@ -44,12 +44,12 @@ fn cosh32(z: Complex(f32)) Complex(f32) { | ... | @@ -44,12 +44,12 @@ fn cosh32(z: Complex(f32)) Complex(f32) { |
| 44 | // |x|>= 9, so cosh(x) ~= exp(|x|) | 44 | // |x|>= 9, so cosh(x) ~= exp(|x|) |
| 45 | if (ix < 0x42b17218) { | 45 | if (ix < 0x42b17218) { |
| 46 | // x < 88.7: exp(|x|) won't overflow | 46 | // x < 88.7: exp(|x|) won't overflow |
| 47 | const h = @exp(@fabs(x)) * 0.5; | 47 | const h = @exp(@abs(x)) * 0.5; |
| 48 | return Complex(f32).init(math.copysign(h, x) * @cos(y), h * @sin(y)); | 48 | return Complex(f32).init(math.copysign(h, x) * @cos(y), h * @sin(y)); |
| 49 | } | 49 | } |
| 50 | // x < 192.7: scale to avoid overflow | 50 | // x < 192.7: scale to avoid overflow |
| 51 | else if (ix < 0x4340b1e7) { | 51 | else if (ix < 0x4340b1e7) { |
| 52 | const v = Complex(f32).init(@fabs(x), y); | 52 | const v = Complex(f32).init(@abs(x), y); |
| 53 | const r = ldexp_cexp(v, -1); | 53 | const r = ldexp_cexp(v, -1); |
| 54 | return Complex(f32).init(r.re, r.im * math.copysign(@as(f32, 1.0), x)); | 54 | return Complex(f32).init(r.re, r.im * math.copysign(@as(f32, 1.0), x)); |
| 55 | } | 55 | } |
| ... | @@ -112,12 +112,12 @@ fn cosh64(z: Complex(f64)) Complex(f64) { | ... | @@ -112,12 +112,12 @@ fn cosh64(z: Complex(f64)) Complex(f64) { |
| 112 | // |x|>= 22, so cosh(x) ~= exp(|x|) | 112 | // |x|>= 22, so cosh(x) ~= exp(|x|) |
| 113 | if (ix < 0x40862e42) { | 113 | if (ix < 0x40862e42) { |
| 114 | // x < 710: exp(|x|) won't overflow | 114 | // x < 710: exp(|x|) won't overflow |
| 115 | const h = @exp(@fabs(x)) * 0.5; | 115 | const h = @exp(@abs(x)) * 0.5; |
| 116 | return Complex(f64).init(h * @cos(y), math.copysign(h, x) * @sin(y)); | 116 | return Complex(f64).init(h * @cos(y), math.copysign(h, x) * @sin(y)); |
| 117 | } | 117 | } |
| 118 | // x < 1455: scale to avoid overflow | 118 | // x < 1455: scale to avoid overflow |
| 119 | else if (ix < 0x4096bbaa) { | 119 | else if (ix < 0x4096bbaa) { |
| 120 | const v = Complex(f64).init(@fabs(x), y); | 120 | const v = Complex(f64).init(@abs(x), y); |
| 121 | const r = ldexp_cexp(v, -1); | 121 | const r = ldexp_cexp(v, -1); |
| 122 | return Complex(f64).init(r.re, r.im * math.copysign(@as(f64, 1.0), x)); | 122 | return Complex(f64).init(r.re, r.im * math.copysign(@as(f64, 1.0), x)); |
| 123 | } | 123 | } |
lib/std/math/complex/sinh.zig+4-4| ... | @@ -44,12 +44,12 @@ fn sinh32(z: Complex(f32)) Complex(f32) { | ... | @@ -44,12 +44,12 @@ fn sinh32(z: Complex(f32)) Complex(f32) { |
| 44 | // |x|>= 9, so cosh(x) ~= exp(|x|) | 44 | // |x|>= 9, so cosh(x) ~= exp(|x|) |
| 45 | if (ix < 0x42b17218) { | 45 | if (ix < 0x42b17218) { |
| 46 | // x < 88.7: exp(|x|) won't overflow | 46 | // x < 88.7: exp(|x|) won't overflow |
| 47 | const h = @exp(@fabs(x)) * 0.5; | 47 | const h = @exp(@abs(x)) * 0.5; |
| 48 | return Complex(f32).init(math.copysign(h, x) * @cos(y), h * @sin(y)); | 48 | return Complex(f32).init(math.copysign(h, x) * @cos(y), h * @sin(y)); |
| 49 | } | 49 | } |
| 50 | // x < 192.7: scale to avoid overflow | 50 | // x < 192.7: scale to avoid overflow |
| 51 | else if (ix < 0x4340b1e7) { | 51 | else if (ix < 0x4340b1e7) { |
| 52 | const v = Complex(f32).init(@fabs(x), y); | 52 | const v = Complex(f32).init(@abs(x), y); |
| 53 | const r = ldexp_cexp(v, -1); | 53 | const r = ldexp_cexp(v, -1); |
| 54 | return Complex(f32).init(r.re * math.copysign(@as(f32, 1.0), x), r.im); | 54 | return Complex(f32).init(r.re * math.copysign(@as(f32, 1.0), x), r.im); |
| 55 | } | 55 | } |
| ... | @@ -111,12 +111,12 @@ fn sinh64(z: Complex(f64)) Complex(f64) { | ... | @@ -111,12 +111,12 @@ fn sinh64(z: Complex(f64)) Complex(f64) { |
| 111 | // |x|>= 22, so cosh(x) ~= exp(|x|) | 111 | // |x|>= 22, so cosh(x) ~= exp(|x|) |
| 112 | if (ix < 0x40862e42) { | 112 | if (ix < 0x40862e42) { |
| 113 | // x < 710: exp(|x|) won't overflow | 113 | // x < 710: exp(|x|) won't overflow |
| 114 | const h = @exp(@fabs(x)) * 0.5; | 114 | const h = @exp(@abs(x)) * 0.5; |
| 115 | return Complex(f64).init(math.copysign(h, x) * @cos(y), h * @sin(y)); | 115 | return Complex(f64).init(math.copysign(h, x) * @cos(y), h * @sin(y)); |
| 116 | } | 116 | } |
| 117 | // x < 1455: scale to avoid overflow | 117 | // x < 1455: scale to avoid overflow |
| 118 | else if (ix < 0x4096bbaa) { | 118 | else if (ix < 0x4096bbaa) { |
| 119 | const v = Complex(f64).init(@fabs(x), y); | 119 | const v = Complex(f64).init(@abs(x), y); |
| 120 | const r = ldexp_cexp(v, -1); | 120 | const r = ldexp_cexp(v, -1); |
| 121 | return Complex(f64).init(r.re * math.copysign(@as(f64, 1.0), x), r.im); | 121 | return Complex(f64).init(r.re * math.copysign(@as(f64, 1.0), x), r.im); |
| 122 | } | 122 | } |
lib/std/math/complex/sqrt.zig+5-5| ... | @@ -43,7 +43,7 @@ fn sqrt32(z: Complex(f32)) Complex(f32) { | ... | @@ -43,7 +43,7 @@ fn sqrt32(z: Complex(f32)) Complex(f32) { |
| 43 | // sqrt(-inf + i nan) = nan +- inf i | 43 | // sqrt(-inf + i nan) = nan +- inf i |
| 44 | // sqrt(-inf + iy) = 0 + inf i | 44 | // sqrt(-inf + iy) = 0 + inf i |
| 45 | if (math.signbit(x)) { | 45 | if (math.signbit(x)) { |
| 46 | return Complex(f32).init(@fabs(x - y), math.copysign(x, y)); | 46 | return Complex(f32).init(@abs(x - y), math.copysign(x, y)); |
| 47 | } else { | 47 | } else { |
| 48 | return Complex(f32).init(x, math.copysign(y - y, y)); | 48 | return Complex(f32).init(x, math.copysign(y - y, y)); |
| 49 | } | 49 | } |
| ... | @@ -64,7 +64,7 @@ fn sqrt32(z: Complex(f32)) Complex(f32) { | ... | @@ -64,7 +64,7 @@ fn sqrt32(z: Complex(f32)) Complex(f32) { |
| 64 | } else { | 64 | } else { |
| 65 | const t = @sqrt((-dx + math.hypot(f64, dx, dy)) * 0.5); | 65 | const t = @sqrt((-dx + math.hypot(f64, dx, dy)) * 0.5); |
| 66 | return Complex(f32).init( | 66 | return Complex(f32).init( |
| 67 | @as(f32, @floatCast(@fabs(y) / (2.0 * t))), | 67 | @as(f32, @floatCast(@abs(y) / (2.0 * t))), |
| 68 | @as(f32, @floatCast(math.copysign(t, y))), | 68 | @as(f32, @floatCast(math.copysign(t, y))), |
| 69 | ); | 69 | ); |
| 70 | } | 70 | } |
| ... | @@ -94,7 +94,7 @@ fn sqrt64(z: Complex(f64)) Complex(f64) { | ... | @@ -94,7 +94,7 @@ fn sqrt64(z: Complex(f64)) Complex(f64) { |
| 94 | // sqrt(-inf + i nan) = nan +- inf i | 94 | // sqrt(-inf + i nan) = nan +- inf i |
| 95 | // sqrt(-inf + iy) = 0 + inf i | 95 | // sqrt(-inf + iy) = 0 + inf i |
| 96 | if (math.signbit(x)) { | 96 | if (math.signbit(x)) { |
| 97 | return Complex(f64).init(@fabs(x - y), math.copysign(x, y)); | 97 | return Complex(f64).init(@abs(x - y), math.copysign(x, y)); |
| 98 | } else { | 98 | } else { |
| 99 | return Complex(f64).init(x, math.copysign(y - y, y)); | 99 | return Complex(f64).init(x, math.copysign(y - y, y)); |
| 100 | } | 100 | } |
| ... | @@ -104,7 +104,7 @@ fn sqrt64(z: Complex(f64)) Complex(f64) { | ... | @@ -104,7 +104,7 @@ fn sqrt64(z: Complex(f64)) Complex(f64) { |
| 104 | 104 | ||
| 105 | // scale to avoid overflow | 105 | // scale to avoid overflow |
| 106 | var scale = false; | 106 | var scale = false; |
| 107 | if (@fabs(x) >= threshold or @fabs(y) >= threshold) { | 107 | if (@abs(x) >= threshold or @abs(y) >= threshold) { |
| 108 | x *= 0.25; | 108 | x *= 0.25; |
| 109 | y *= 0.25; | 109 | y *= 0.25; |
| 110 | scale = true; | 110 | scale = true; |
| ... | @@ -116,7 +116,7 @@ fn sqrt64(z: Complex(f64)) Complex(f64) { | ... | @@ -116,7 +116,7 @@ fn sqrt64(z: Complex(f64)) Complex(f64) { |
| 116 | result = Complex(f64).init(t, y / (2.0 * t)); | 116 | result = Complex(f64).init(t, y / (2.0 * t)); |
| 117 | } else { | 117 | } else { |
| 118 | const t = @sqrt((-x + math.hypot(f64, x, y)) * 0.5); | 118 | const t = @sqrt((-x + math.hypot(f64, x, y)) * 0.5); |
| 119 | result = Complex(f64).init(@fabs(y) / (2.0 * t), math.copysign(t, y)); | 119 | result = Complex(f64).init(@abs(y) / (2.0 * t), math.copysign(t, y)); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | if (scale) { | 122 | if (scale) { |
lib/std/math/complex/tanh.zig+2-2| ... | @@ -44,7 +44,7 @@ fn tanh32(z: Complex(f32)) Complex(f32) { | ... | @@ -44,7 +44,7 @@ fn tanh32(z: Complex(f32)) Complex(f32) { |
| 44 | 44 | ||
| 45 | // x >= 11 | 45 | // x >= 11 |
| 46 | if (ix >= 0x41300000) { | 46 | if (ix >= 0x41300000) { |
| 47 | const exp_mx = @exp(-@fabs(x)); | 47 | const exp_mx = @exp(-@abs(x)); |
| 48 | return Complex(f32).init(math.copysign(@as(f32, 1.0), x), 4 * @sin(y) * @cos(y) * exp_mx * exp_mx); | 48 | return Complex(f32).init(math.copysign(@as(f32, 1.0), x), 4 * @sin(y) * @cos(y) * exp_mx * exp_mx); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| ... | @@ -87,7 +87,7 @@ fn tanh64(z: Complex(f64)) Complex(f64) { | ... | @@ -87,7 +87,7 @@ fn tanh64(z: Complex(f64)) Complex(f64) { |
| 87 | 87 | ||
| 88 | // x >= 22 | 88 | // x >= 22 |
| 89 | if (ix >= 0x40360000) { | 89 | if (ix >= 0x40360000) { |
| 90 | const exp_mx = @exp(-@fabs(x)); | 90 | const exp_mx = @exp(-@abs(x)); |
| 91 | return Complex(f64).init(math.copysign(@as(f64, 1.0), x), 4 * @sin(y) * @cos(y) * exp_mx * exp_mx); | 91 | return Complex(f64).init(math.copysign(@as(f64, 1.0), x), 4 * @sin(y) * @cos(y) * exp_mx * exp_mx); |
| 92 | } | 92 | } |
| 93 | 93 |
lib/std/math/pow.zig+2-2| ... | @@ -82,7 +82,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { | ... | @@ -82,7 +82,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { |
| 82 | } | 82 | } |
| 83 | // pow(x, +inf) = +0 for |x| < 1 | 83 | // pow(x, +inf) = +0 for |x| < 1 |
| 84 | // pow(x, -inf) = +0 for |x| > 1 | 84 | // pow(x, -inf) = +0 for |x| > 1 |
| 85 | else if ((@fabs(x) < 1) == math.isPositiveInf(y)) { | 85 | else if ((@abs(x) < 1) == math.isPositiveInf(y)) { |
| 86 | return 0; | 86 | return 0; |
| 87 | } | 87 | } |
| 88 | // pow(x, -inf) = +inf for |x| < 1 | 88 | // pow(x, -inf) = +inf for |x| < 1 |
| ... | @@ -115,7 +115,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { | ... | @@ -115,7 +115,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { |
| 115 | return 1 / @sqrt(x); | 115 | return 1 / @sqrt(x); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | const r1 = math.modf(@fabs(y)); | 118 | const r1 = math.modf(@abs(y)); |
| 119 | var yi = r1.ipart; | 119 | var yi = r1.ipart; |
| 120 | var yf = r1.fpart; | 120 | var yf = r1.fpart; |
| 121 | 121 |
lib/std/meta.zig+2-2| ... | @@ -1104,6 +1104,6 @@ pub fn isError(error_union: anytype) bool { | ... | @@ -1104,6 +1104,6 @@ pub fn isError(error_union: anytype) bool { |
| 1104 | } | 1104 | } |
| 1105 | 1105 | ||
| 1106 | test "isError" { | 1106 | test "isError" { |
| 1107 | try std.testing.expect(isError(math.absInt(@as(i8, -128)))); | 1107 | try std.testing.expect(isError(math.divTrunc(u8, 5, 0))); |
| 1108 | try std.testing.expect(!isError(math.absInt(@as(i8, -127)))); | 1108 | try std.testing.expect(!isError(math.divTrunc(u8, 5, 5))); |
| 1109 | } | 1109 | } |
lib/std/rand/ziggurat.zig+1-1| ... | @@ -33,7 +33,7 @@ pub fn next_f64(random: Random, comptime tables: ZigTable) f64 { | ... | @@ -33,7 +33,7 @@ pub fn next_f64(random: Random, comptime tables: ZigTable) f64 { |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | const x = u * tables.x[i]; | 35 | const x = u * tables.x[i]; |
| 36 | const test_x = if (tables.is_symmetric) @fabs(x) else x; | 36 | const test_x = if (tables.is_symmetric) @abs(x) else x; |
| 37 | 37 | ||
| 38 | // equivalent to |u| < tables.x[i+1] / tables.x[i] (or u < tables.x[i+1] / tables.x[i]) | 38 | // equivalent to |u| < tables.x[i+1] / tables.x[i] (or u < tables.x[i+1] / tables.x[i]) |
| 39 | if (test_x < tables.x[i + 1]) { | 39 | if (test_x < tables.x[i + 1]) { |
lib/std/zig/c_builtins.zig+9-3| ... | @@ -88,13 +88,19 @@ pub inline fn __builtin_log10f(val: f32) f32 { | ... | @@ -88,13 +88,19 @@ pub inline fn __builtin_log10f(val: f32) f32 { |
| 88 | 88 | ||
| 89 | // Standard C Library bug: The absolute value of the most negative integer remains negative. | 89 | // Standard C Library bug: The absolute value of the most negative integer remains negative. |
| 90 | pub inline fn __builtin_abs(val: c_int) c_int { | 90 | pub inline fn __builtin_abs(val: c_int) c_int { |
| 91 | return std.math.absInt(val) catch std.math.minInt(c_int); | 91 | return if (val == std.math.minInt(c_int)) val else @intCast(@abs(val)); |
| 92 | } | ||
| 93 | pub inline fn __builtin_labs(val: c_long) c_long { | ||
| 94 | return if (val == std.math.minInt(c_long)) val else @intCast(@abs(val)); | ||
| 95 | } | ||
| 96 | pub inline fn __builtin_llabs(val: c_longlong) c_longlong { | ||
| 97 | return if (val == std.math.minInt(c_longlong)) val else @intCast(@abs(val)); | ||
| 92 | } | 98 | } |
| 93 | pub inline fn __builtin_fabs(val: f64) f64 { | 99 | pub inline fn __builtin_fabs(val: f64) f64 { |
| 94 | return @fabs(val); | 100 | return @abs(val); |
| 95 | } | 101 | } |
| 96 | pub inline fn __builtin_fabsf(val: f32) f32 { | 102 | pub inline fn __builtin_fabsf(val: f32) f32 { |
| 97 | return @fabs(val); | 103 | return @abs(val); |
| 98 | } | 104 | } |
| 99 | 105 | ||
| 100 | pub inline fn __builtin_floor(val: f64) f64 { | 106 | pub inline fn __builtin_floor(val: f64) f64 { |
lib/zig.h+41| ... | @@ -946,6 +946,24 @@ typedef unsigned long zig_Builtin64; | ... | @@ -946,6 +946,24 @@ typedef unsigned long zig_Builtin64; |
| 946 | typedef unsigned long long zig_Builtin64; | 946 | typedef unsigned long long zig_Builtin64; |
| 947 | #endif | 947 | #endif |
| 948 | 948 | ||
| 949 | #define zig_builtin8_rev(name, val) __builtin_##name(val) | ||
| 950 | |||
| 951 | #define zig_builtin16_rev(name, val) __builtin_##name(val) | ||
| 952 | |||
| 953 | #if INT_MIN <= INT32_MIN | ||
| 954 | #define zig_builtin32_rev(name, val) __builtin_##name(val) | ||
| 955 | #elif LONG_MIN <= INT32_MIN | ||
| 956 | #define zig_builtin32_rev(name, val) __builtin_l##name(val) | ||
| 957 | #endif | ||
| 958 | |||
| 959 | #if INT_MIN <= INT64_MIN | ||
| 960 | #define zig_builtin64_rev(name, val) __builtin_##name(val) | ||
| 961 | #elif LONG_MIN <= INT64_MIN | ||
| 962 | #define zig_builtin64_rev(name, val) __builtin_l##name(val) | ||
| 963 | #elif LLONG_MIN <= INT64_MIN | ||
| 964 | #define zig_builtin64_rev(name, val) __builtin_ll##name(val) | ||
| 965 | #endif | ||
| 966 | |||
| 949 | static inline uint8_t zig_byte_swap_u8(uint8_t val, uint8_t bits) { | 967 | static inline uint8_t zig_byte_swap_u8(uint8_t val, uint8_t bits) { |
| 950 | return zig_wrap_u8(val >> (8 - bits), bits); | 968 | return zig_wrap_u8(val >> (8 - bits), bits); |
| 951 | } | 969 | } |
| ... | @@ -1141,6 +1159,24 @@ zig_builtin_clz(16) | ... | @@ -1141,6 +1159,24 @@ zig_builtin_clz(16) |
| 1141 | zig_builtin_clz(32) | 1159 | zig_builtin_clz(32) |
| 1142 | zig_builtin_clz(64) | 1160 | zig_builtin_clz(64) |
| 1143 | 1161 | ||
| 1162 | #if zig_has_builtin(abs) || defined(zig_gnuc) | ||
| 1163 | #define zig_builtin_abs(w) \ | ||
| 1164 | static inline int##w##_t zig_abs_i##w(int##w##_t val) { \ | ||
| 1165 | return zig_builtin##w##_rev(abs, val); \ | ||
| 1166 | } | ||
| 1167 | #else | ||
| 1168 | #define zig_builtin_abs(w) \ | ||
| 1169 | static inline int##w##_t zig_abs_i##w(int##w##_t val) { \ | ||
| 1170 | if (val == INT##w##_MIN) return val; \ | ||
| 1171 | int##w##_t tmp = val >> (w - 1); \ | ||
| 1172 | return (val ^ tmp) - tmp; \ | ||
| 1173 | } | ||
| 1174 | #endif | ||
| 1175 | zig_builtin_abs(8) | ||
| 1176 | zig_builtin_abs(16) | ||
| 1177 | zig_builtin_abs(32) | ||
| 1178 | zig_builtin_abs(64) | ||
| 1179 | |||
| 1144 | /* ======================== 128-bit Integer Support ========================= */ | 1180 | /* ======================== 128-bit Integer Support ========================= */ |
| 1145 | 1181 | ||
| 1146 | #if !defined(zig_has_int128) | 1182 | #if !defined(zig_has_int128) |
| ... | @@ -1466,6 +1502,11 @@ static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | ... | @@ -1466,6 +1502,11 @@ static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 1466 | return zig_wrap_i128(zig_bitCast_i128(zig_mul_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits); | 1502 | return zig_wrap_i128(zig_bitCast_i128(zig_mul_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits); |
| 1467 | } | 1503 | } |
| 1468 | 1504 | ||
| 1505 | static inline zig_u128 zig_abs_i128(zig_i128 val) { | ||
| 1506 | zig_i128 tmp = zig_shr_i128(val, 127); | ||
| 1507 | return zig_bitCast_u128(zig_sub_i128(zig_xor_i128(val, tmp), tmp)); | ||
| 1508 | } | ||
| 1509 | |||
| 1469 | #if zig_has_int128 | 1510 | #if zig_has_int128 |
| 1470 | 1511 | ||
| 1471 | static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 1512 | static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |