diff options
| author | Anthony Arian <anthonyarian96@gmail.com> | 2020-07-20 10:25:54 +0100 |
|---|---|---|
| committer | Anthony Arian <anthonyarian96@gmail.com> | 2020-07-20 10:25:54 +0100 |
| commit | 3658dd5e89cd16c011bdc52d334c1308f440157b (patch) | |
| tree | 09564ab2db65acc4a52d82bccbf0eb572fbc865f /lib/std/math | |
| parent | 68fe3e116d9c4bde67df990b8e0cbb3e70fc98b2 (diff) | |
| parent | 596ca6cf70cf43c27e31bbcfc36bcdc70b13897a (diff) | |
| download | zig-3658dd5e89cd16c011bdc52d334c1308f440157b.tar.gz zig-3658dd5e89cd16c011bdc52d334c1308f440157b.zip | |
Merge branch 'master' of https://github.com/ziglang/zig into 5002-fix-entrypoint-with-winmain
Diffstat (limited to 'lib/std/math')
58 files changed, 245 insertions, 72 deletions
diff --git a/lib/std/math/acos.zig b/lib/std/math/acos.zig index aec0d4706a..cdd86601fd 100644 --- a/lib/std/math/acos.zig +++ b/lib/std/math/acos.zig @@ -12,7 +12,7 @@ const expect = std.testing.expect; /// /// Special cases: /// - acos(x) = nan if x < -1 or x > 1 -pub fn acos(x: var) @TypeOf(x) { +pub fn acos(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => acos32(x), diff --git a/lib/std/math/acosh.zig b/lib/std/math/acosh.zig index 0f99335058..9a594f9cc4 100644 --- a/lib/std/math/acosh.zig +++ b/lib/std/math/acosh.zig @@ -14,7 +14,7 @@ const expect = std.testing.expect; /// Special cases: /// - acosh(x) = snan if x < 1 /// - acosh(nan) = nan -pub fn acosh(x: var) @TypeOf(x) { +pub fn acosh(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => acosh32(x), diff --git a/lib/std/math/asin.zig b/lib/std/math/asin.zig index db57e2088f..4cff69fc1b 100644 --- a/lib/std/math/asin.zig +++ b/lib/std/math/asin.zig @@ -13,7 +13,7 @@ const expect = std.testing.expect; /// Special Cases: /// - asin(+-0) = +-0 /// - asin(x) = nan if x < -1 or x > 1 -pub fn asin(x: var) @TypeOf(x) { +pub fn asin(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => asin32(x), diff --git a/lib/std/math/asinh.zig b/lib/std/math/asinh.zig index ab1b650139..940b953d06 100644 --- a/lib/std/math/asinh.zig +++ b/lib/std/math/asinh.zig @@ -15,7 +15,7 @@ const maxInt = std.math.maxInt; /// - asinh(+-0) = +-0 /// - asinh(+-inf) = +-inf /// - asinh(nan) = nan -pub fn asinh(x: var) @TypeOf(x) { +pub fn asinh(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => asinh32(x), diff --git a/lib/std/math/atan.zig b/lib/std/math/atan.zig index eb9154b5fe..9342b6ed59 100644 --- a/lib/std/math/atan.zig +++ b/lib/std/math/atan.zig @@ -13,7 +13,7 @@ const expect = std.testing.expect; /// Special Cases: /// - atan(+-0) = +-0 /// - atan(+-inf) = +-pi/2 -pub fn atan(x: var) @TypeOf(x) { +pub fn atan(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => atan32(x), diff --git a/lib/std/math/atanh.zig b/lib/std/math/atanh.zig index e58a10fff5..de742bd4cd 100644 --- a/lib/std/math/atanh.zig +++ b/lib/std/math/atanh.zig @@ -15,7 +15,7 @@ const maxInt = std.math.maxInt; /// - atanh(+-1) = +-inf with signal /// - atanh(x) = nan if |x| > 1 with signal /// - atanh(nan) = nan -pub fn atanh(x: var) @TypeOf(x) { +pub fn atanh(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => atanh_32(x), diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index 9379f881db..b6d7731f1a 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -12,7 +12,7 @@ const assert = std.debug.assert; /// Returns the number of limbs needed to store `scalar`, which must be a /// primitive integer value. -pub fn calcLimbLen(scalar: var) usize { +pub fn calcLimbLen(scalar: anytype) usize { const T = @TypeOf(scalar); switch (@typeInfo(T)) { .Int => |info| { @@ -110,7 +110,7 @@ pub const Mutable = struct { /// `value` is a primitive integer type. /// Asserts the value fits within the provided `limbs_buffer`. /// Note: `calcLimbLen` can be used to figure out how big an array to allocate for `limbs_buffer`. - pub fn init(limbs_buffer: []Limb, value: var) Mutable { + pub fn init(limbs_buffer: []Limb, value: anytype) Mutable { limbs_buffer[0] = 0; var self: Mutable = .{ .limbs = limbs_buffer, @@ -169,7 +169,7 @@ pub const Mutable = struct { /// Asserts the value fits within the limbs buffer. /// Note: `calcLimbLen` can be used to figure out how big the limbs buffer /// needs to be to store a specific value. - pub fn set(self: *Mutable, value: var) void { + pub fn set(self: *Mutable, value: anytype) void { const T = @TypeOf(value); switch (@typeInfo(T)) { @@ -281,7 +281,7 @@ pub const Mutable = struct { /// /// Asserts the result fits in `r`. An upper bound on the number of limbs needed by /// r is `math.max(a.limbs.len, calcLimbLen(scalar)) + 1`. - pub fn addScalar(r: *Mutable, a: Const, scalar: var) void { + pub fn addScalar(r: *Mutable, a: Const, scalar: anytype) void { var limbs: [calcLimbLen(scalar)]Limb = undefined; const operand = init(&limbs, scalar).toConst(); return add(r, a, operand); @@ -1058,7 +1058,7 @@ pub const Const = struct { self: Const, comptime fmt: []const u8, options: std.fmt.FormatOptions, - out_stream: var, + out_stream: anytype, ) !void { comptime var radix = 10; comptime var uppercase = false; @@ -1105,7 +1105,7 @@ pub const Const = struct { assert(base <= 16); if (self.eqZero()) { - return mem.dupe(allocator, u8, "0"); + return allocator.dupe(u8, "0"); } const string = try allocator.alloc(u8, self.sizeInBaseUpperBound(base)); errdefer allocator.free(string); @@ -1261,7 +1261,7 @@ pub const Const = struct { } /// Same as `order` but the right-hand operand is a primitive integer. - pub fn orderAgainstScalar(lhs: Const, scalar: var) math.Order { + pub fn orderAgainstScalar(lhs: Const, scalar: anytype) math.Order { var limbs: [calcLimbLen(scalar)]Limb = undefined; const rhs = Mutable.init(&limbs, scalar); return order(lhs, rhs.toConst()); @@ -1333,7 +1333,7 @@ pub const Managed = struct { /// Creates a new `Managed` with value `value`. /// /// This is identical to an `init`, followed by a `set`. - pub fn initSet(allocator: *Allocator, value: var) !Managed { + pub fn initSet(allocator: *Allocator, value: anytype) !Managed { var s = try Managed.init(allocator); try s.set(value); return s; @@ -1496,7 +1496,7 @@ pub const Managed = struct { } /// Sets an Managed to value. Value must be an primitive integer type. - pub fn set(self: *Managed, value: var) Allocator.Error!void { + pub fn set(self: *Managed, value: anytype) Allocator.Error!void { try self.ensureCapacity(calcLimbLen(value)); var m = self.toMutable(); m.set(value); @@ -1549,7 +1549,7 @@ pub const Managed = struct { self: Managed, comptime fmt: []const u8, options: std.fmt.FormatOptions, - out_stream: var, + out_stream: anytype, ) !void { return self.toConst().format(fmt, options, out_stream); } @@ -1607,7 +1607,7 @@ pub const Managed = struct { /// scalar is a primitive integer type. /// /// Returns an error if memory could not be allocated. - pub fn addScalar(r: *Managed, a: Const, scalar: var) Allocator.Error!void { + pub fn addScalar(r: *Managed, a: Const, scalar: anytype) Allocator.Error!void { try r.ensureCapacity(math.max(a.limbs.len, calcLimbLen(scalar)) + 1); var m = r.toMutable(); m.addScalar(a, scalar); diff --git a/lib/std/math/big/rational.zig b/lib/std/math/big/rational.zig index 3624a16139..6f62a462b8 100644 --- a/lib/std/math/big/rational.zig +++ b/lib/std/math/big/rational.zig @@ -43,7 +43,7 @@ pub const Rational = struct { } /// Set a Rational from a primitive integer type. - pub fn setInt(self: *Rational, a: var) !void { + pub fn setInt(self: *Rational, a: anytype) !void { try self.p.set(a); try self.q.set(1); } @@ -280,7 +280,7 @@ pub const Rational = struct { } /// Set a rational from an integer ratio. - pub fn setRatio(self: *Rational, p: var, q: var) !void { + pub fn setRatio(self: *Rational, p: anytype, q: anytype) !void { try self.p.set(p); try self.q.set(q); diff --git a/lib/std/math/cbrt.zig b/lib/std/math/cbrt.zig index 2b219d5368..42163b96dc 100644 --- a/lib/std/math/cbrt.zig +++ b/lib/std/math/cbrt.zig @@ -14,7 +14,7 @@ const expect = std.testing.expect; /// - cbrt(+-0) = +-0 /// - cbrt(+-inf) = +-inf /// - cbrt(nan) = nan -pub fn cbrt(x: var) @TypeOf(x) { +pub fn cbrt(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => cbrt32(x), diff --git a/lib/std/math/ceil.zig b/lib/std/math/ceil.zig index b94e13a176..39de46f361 100644 --- a/lib/std/math/ceil.zig +++ b/lib/std/math/ceil.zig @@ -15,11 +15,12 @@ const expect = std.testing.expect; /// - ceil(+-0) = +-0 /// - ceil(+-inf) = +-inf /// - ceil(nan) = nan -pub fn ceil(x: var) @TypeOf(x) { +pub fn ceil(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => ceil32(x), f64 => ceil64(x), + f128 => ceil128(x), else => @compileError("ceil not implemented for " ++ @typeName(T)), }; } @@ -86,9 +87,37 @@ fn ceil64(x: f64) f64 { } } +fn ceil128(x: f128) f128 { + const u = @bitCast(u128, x); + const e = (u >> 112) & 0x7FFF; + var y: f128 = undefined; + + if (e >= 0x3FFF + 112 or x == 0) return x; + + if (u >> 127 != 0) { + y = x - math.f128_toint + math.f128_toint - x; + } else { + y = x + math.f128_toint - math.f128_toint - x; + } + + if (e <= 0x3FFF - 1) { + math.forceEval(y); + if (u >> 127 != 0) { + return -0.0; + } else { + return 1.0; + } + } else if (y < 0) { + return x + y + 1; + } else { + return x + y; + } +} + test "math.ceil" { expect(ceil(@as(f32, 0.0)) == ceil32(0.0)); expect(ceil(@as(f64, 0.0)) == ceil64(0.0)); + expect(ceil(@as(f128, 0.0)) == ceil128(0.0)); } test "math.ceil32" { @@ -103,6 +132,12 @@ test "math.ceil64" { expect(ceil64(0.2) == 1.0); } +test "math.ceil128" { + expect(ceil128(1.3) == 2.0); + expect(ceil128(-1.3) == -1.0); + expect(ceil128(0.2) == 1.0); +} + test "math.ceil32.special" { expect(ceil32(0.0) == 0.0); expect(ceil32(-0.0) == -0.0); @@ -118,3 +153,11 @@ test "math.ceil64.special" { expect(math.isNegativeInf(ceil64(-math.inf(f64)))); expect(math.isNan(ceil64(math.nan(f64)))); } + +test "math.ceil128.special" { + expect(ceil128(0.0) == 0.0); + expect(ceil128(-0.0) == -0.0); + expect(math.isPositiveInf(ceil128(math.inf(f128)))); + expect(math.isNegativeInf(ceil128(-math.inf(f128)))); + expect(math.isNan(ceil128(math.nan(f128)))); +} diff --git a/lib/std/math/complex/abs.zig b/lib/std/math/complex/abs.zig index 75b967f3d2..db31aef42a 100644 --- a/lib/std/math/complex/abs.zig +++ b/lib/std/math/complex/abs.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the absolute value (modulus) of z. -pub fn abs(z: var) @TypeOf(z.re) { +pub fn abs(z: anytype) @TypeOf(z.re) { const T = @TypeOf(z.re); return math.hypot(T, z.re, z.im); } diff --git a/lib/std/math/complex/acos.zig b/lib/std/math/complex/acos.zig index 24a645375c..072fd77f08 100644 --- a/lib/std/math/complex/acos.zig +++ b/lib/std/math/complex/acos.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the arc-cosine of z. -pub fn acos(z: var) Complex(@TypeOf(z.re)) { +pub fn acos(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); const q = cmath.asin(z); return Complex(T).new(@as(T, math.pi) / 2 - q.re, -q.im); diff --git a/lib/std/math/complex/acosh.zig b/lib/std/math/complex/acosh.zig index 996334034a..59117a8b27 100644 --- a/lib/std/math/complex/acosh.zig +++ b/lib/std/math/complex/acosh.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the hyperbolic arc-cosine of z. -pub fn acosh(z: var) Complex(@TypeOf(z.re)) { +pub fn acosh(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); const q = cmath.acos(z); return Complex(T).new(-q.im, q.re); diff --git a/lib/std/math/complex/arg.zig b/lib/std/math/complex/arg.zig index f690e92143..6cf959a081 100644 --- a/lib/std/math/complex/arg.zig +++ b/lib/std/math/complex/arg.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the angular component (in radians) of z. -pub fn arg(z: var) @TypeOf(z.re) { +pub fn arg(z: anytype) @TypeOf(z.re) { const T = @TypeOf(z.re); return math.atan2(T, z.im, z.re); } diff --git a/lib/std/math/complex/asin.zig b/lib/std/math/complex/asin.zig index 01fa33156a..9f7cd396aa 100644 --- a/lib/std/math/complex/asin.zig +++ b/lib/std/math/complex/asin.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; // Returns the arc-sine of z. -pub fn asin(z: var) Complex(@TypeOf(z.re)) { +pub fn asin(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); const x = z.re; const y = z.im; diff --git a/lib/std/math/complex/asinh.zig b/lib/std/math/complex/asinh.zig index 47d8244adb..0c3c2bd115 100644 --- a/lib/std/math/complex/asinh.zig +++ b/lib/std/math/complex/asinh.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the hyperbolic arc-sine of z. -pub fn asinh(z: var) Complex(@TypeOf(z.re)) { +pub fn asinh(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); const q = Complex(T).new(-z.im, z.re); const r = cmath.asin(q); diff --git a/lib/std/math/complex/atan.zig b/lib/std/math/complex/atan.zig index 5ba6f7b0d2..98bde3e125 100644 --- a/lib/std/math/complex/atan.zig +++ b/lib/std/math/complex/atan.zig @@ -12,7 +12,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the arc-tangent of z. -pub fn atan(z: var) @TypeOf(z) { +pub fn atan(z: anytype) @TypeOf(z) { const T = @TypeOf(z.re); return switch (T) { f32 => atan32(z), diff --git a/lib/std/math/complex/atanh.zig b/lib/std/math/complex/atanh.zig index 8b70306224..a07c2969e4 100644 --- a/lib/std/math/complex/atanh.zig +++ b/lib/std/math/complex/atanh.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the hyperbolic arc-tangent of z. -pub fn atanh(z: var) Complex(@TypeOf(z.re)) { +pub fn atanh(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); const q = Complex(T).new(-z.im, z.re); const r = cmath.atan(q); diff --git a/lib/std/math/complex/conj.zig b/lib/std/math/complex/conj.zig index 1065d4bb73..42a34e7dfc 100644 --- a/lib/std/math/complex/conj.zig +++ b/lib/std/math/complex/conj.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the complex conjugate of z. -pub fn conj(z: var) Complex(@TypeOf(z.re)) { +pub fn conj(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); return Complex(T).new(z.re, -z.im); } diff --git a/lib/std/math/complex/cos.zig b/lib/std/math/complex/cos.zig index 1aefa73db5..9daf89c730 100644 --- a/lib/std/math/complex/cos.zig +++ b/lib/std/math/complex/cos.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the cosine of z. -pub fn cos(z: var) Complex(@TypeOf(z.re)) { +pub fn cos(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); const p = Complex(T).new(-z.im, z.re); return cmath.cosh(p); diff --git a/lib/std/math/complex/cosh.zig b/lib/std/math/complex/cosh.zig index a9ac893602..bd51629bd4 100644 --- a/lib/std/math/complex/cosh.zig +++ b/lib/std/math/complex/cosh.zig @@ -14,7 +14,7 @@ const Complex = cmath.Complex; const ldexp_cexp = @import("ldexp.zig").ldexp_cexp; /// Returns the hyperbolic arc-cosine of z. -pub fn cosh(z: var) Complex(@TypeOf(z.re)) { +pub fn cosh(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); return switch (T) { f32 => cosh32(z), diff --git a/lib/std/math/complex/exp.zig b/lib/std/math/complex/exp.zig index 9f9e3db807..6f6061a947 100644 --- a/lib/std/math/complex/exp.zig +++ b/lib/std/math/complex/exp.zig @@ -14,7 +14,7 @@ const Complex = cmath.Complex; const ldexp_cexp = @import("ldexp.zig").ldexp_cexp; /// Returns e raised to the power of z (e^z). -pub fn exp(z: var) @TypeOf(z) { +pub fn exp(z: anytype) @TypeOf(z) { const T = @TypeOf(z.re); return switch (T) { diff --git a/lib/std/math/complex/ldexp.zig b/lib/std/math/complex/ldexp.zig index 9eccd4bb98..c23b9b346e 100644 --- a/lib/std/math/complex/ldexp.zig +++ b/lib/std/math/complex/ldexp.zig @@ -11,7 +11,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns exp(z) scaled to avoid overflow. -pub fn ldexp_cexp(z: var, expt: i32) @TypeOf(z) { +pub fn ldexp_cexp(z: anytype, expt: i32) @TypeOf(z) { const T = @TypeOf(z.re); return switch (T) { diff --git a/lib/std/math/complex/log.zig b/lib/std/math/complex/log.zig index f1fad3175e..ec02c6c325 100644 --- a/lib/std/math/complex/log.zig +++ b/lib/std/math/complex/log.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the natural logarithm of z. -pub fn log(z: var) Complex(@TypeOf(z.re)) { +pub fn log(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); const r = cmath.abs(z); const phi = cmath.arg(z); diff --git a/lib/std/math/complex/proj.zig b/lib/std/math/complex/proj.zig index 349f6b3abb..e208ae0370 100644 --- a/lib/std/math/complex/proj.zig +++ b/lib/std/math/complex/proj.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the projection of z onto the riemann sphere. -pub fn proj(z: var) Complex(@TypeOf(z.re)) { +pub fn proj(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); if (math.isInf(z.re) or math.isInf(z.im)) { diff --git a/lib/std/math/complex/sin.zig b/lib/std/math/complex/sin.zig index 87dc57911b..1b10f8fca6 100644 --- a/lib/std/math/complex/sin.zig +++ b/lib/std/math/complex/sin.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the sine of z. -pub fn sin(z: var) Complex(@TypeOf(z.re)) { +pub fn sin(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); const p = Complex(T).new(-z.im, z.re); const q = cmath.sinh(p); diff --git a/lib/std/math/complex/sinh.zig b/lib/std/math/complex/sinh.zig index 7dd880c71c..32f2a730fb 100644 --- a/lib/std/math/complex/sinh.zig +++ b/lib/std/math/complex/sinh.zig @@ -14,7 +14,7 @@ const Complex = cmath.Complex; const ldexp_cexp = @import("ldexp.zig").ldexp_cexp; /// Returns the hyperbolic sine of z. -pub fn sinh(z: var) @TypeOf(z) { +pub fn sinh(z: anytype) @TypeOf(z) { const T = @TypeOf(z.re); return switch (T) { f32 => sinh32(z), diff --git a/lib/std/math/complex/sqrt.zig b/lib/std/math/complex/sqrt.zig index 57e73f6cd1..0edb02a7a9 100644 --- a/lib/std/math/complex/sqrt.zig +++ b/lib/std/math/complex/sqrt.zig @@ -12,7 +12,7 @@ const Complex = cmath.Complex; /// Returns the square root of z. The real and imaginary parts of the result have the same sign /// as the imaginary part of z. -pub fn sqrt(z: var) @TypeOf(z) { +pub fn sqrt(z: anytype) @TypeOf(z) { const T = @TypeOf(z.re); return switch (T) { diff --git a/lib/std/math/complex/tan.zig b/lib/std/math/complex/tan.zig index 70304803db..050898c573 100644 --- a/lib/std/math/complex/tan.zig +++ b/lib/std/math/complex/tan.zig @@ -5,7 +5,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the tanget of z. -pub fn tan(z: var) Complex(@TypeOf(z.re)) { +pub fn tan(z: anytype) Complex(@TypeOf(z.re)) { const T = @TypeOf(z.re); const q = Complex(T).new(-z.im, z.re); const r = cmath.tanh(q); diff --git a/lib/std/math/complex/tanh.zig b/lib/std/math/complex/tanh.zig index afd2e6aee4..1d614cca58 100644 --- a/lib/std/math/complex/tanh.zig +++ b/lib/std/math/complex/tanh.zig @@ -12,7 +12,7 @@ const cmath = math.complex; const Complex = cmath.Complex; /// Returns the hyperbolic tangent of z. -pub fn tanh(z: var) @TypeOf(z) { +pub fn tanh(z: anytype) @TypeOf(z) { const T = @TypeOf(z.re); return switch (T) { f32 => tanh32(z), diff --git a/lib/std/math/cos.zig b/lib/std/math/cos.zig index aa336769b1..df5c0a53be 100644 --- a/lib/std/math/cos.zig +++ b/lib/std/math/cos.zig @@ -13,7 +13,7 @@ const expect = std.testing.expect; /// Special Cases: /// - cos(+-inf) = nan /// - cos(nan) = nan -pub fn cos(x: var) @TypeOf(x) { +pub fn cos(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => cos_(f32, x), diff --git a/lib/std/math/cosh.zig b/lib/std/math/cosh.zig index 1cd8c5f27f..bab47dcdbd 100644 --- a/lib/std/math/cosh.zig +++ b/lib/std/math/cosh.zig @@ -17,7 +17,7 @@ const maxInt = std.math.maxInt; /// - cosh(+-0) = 1 /// - cosh(+-inf) = +inf /// - cosh(nan) = nan -pub fn cosh(x: var) @TypeOf(x) { +pub fn cosh(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => cosh32(x), diff --git a/lib/std/math/exp.zig b/lib/std/math/exp.zig index da80b201c0..c84d929adf 100644 --- a/lib/std/math/exp.zig +++ b/lib/std/math/exp.zig @@ -14,7 +14,7 @@ const builtin = @import("builtin"); /// Special Cases: /// - exp(+inf) = +inf /// - exp(nan) = nan -pub fn exp(x: var) @TypeOf(x) { +pub fn exp(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => exp32(x), diff --git a/lib/std/math/exp2.zig b/lib/std/math/exp2.zig index 411f789187..da391189b2 100644 --- a/lib/std/math/exp2.zig +++ b/lib/std/math/exp2.zig @@ -13,7 +13,7 @@ const expect = std.testing.expect; /// Special Cases: /// - exp2(+inf) = +inf /// - exp2(nan) = nan -pub fn exp2(x: var) @TypeOf(x) { +pub fn exp2(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => exp2_32(x), diff --git a/lib/std/math/expm1.zig b/lib/std/math/expm1.zig index 91752e9f80..80cdefae20 100644 --- a/lib/std/math/expm1.zig +++ b/lib/std/math/expm1.zig @@ -18,7 +18,7 @@ const expect = std.testing.expect; /// - expm1(+inf) = +inf /// - expm1(-inf) = -1 /// - expm1(nan) = nan -pub fn expm1(x: var) @TypeOf(x) { +pub fn expm1(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => expm1_32(x), diff --git a/lib/std/math/expo2.zig b/lib/std/math/expo2.zig index e70e365f26..f404570fb6 100644 --- a/lib/std/math/expo2.zig +++ b/lib/std/math/expo2.zig @@ -7,7 +7,7 @@ const math = @import("../math.zig"); /// Returns exp(x) / 2 for x >= log(maxFloat(T)). -pub fn expo2(x: var) @TypeOf(x) { +pub fn expo2(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => expo2f(x), diff --git a/lib/std/math/fabs.zig b/lib/std/math/fabs.zig index a659e35ca2..ca91f594fd 100644 --- a/lib/std/math/fabs.zig +++ b/lib/std/math/fabs.zig @@ -14,7 +14,7 @@ const maxInt = std.math.maxInt; /// Special Cases: /// - fabs(+-inf) = +inf /// - fabs(nan) = nan -pub fn fabs(x: var) @TypeOf(x) { +pub fn fabs(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f16 => fabs16(x), diff --git a/lib/std/math/floor.zig b/lib/std/math/floor.zig index 1eda362e69..3a71cc7cdf 100644 --- a/lib/std/math/floor.zig +++ b/lib/std/math/floor.zig @@ -15,12 +15,13 @@ const math = std.math; /// - floor(+-0) = +-0 /// - floor(+-inf) = +-inf /// - floor(nan) = nan -pub fn floor(x: var) @TypeOf(x) { +pub fn floor(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f16 => floor16(x), f32 => floor32(x), f64 => floor64(x), + f128 => floor128(x), else => @compileError("floor not implemented for " ++ @typeName(T)), }; } @@ -122,10 +123,38 @@ fn floor64(x: f64) f64 { } } +fn floor128(x: f128) f128 { + const u = @bitCast(u128, x); + const e = (u >> 112) & 0x7FFF; + var y: f128 = undefined; + + if (e >= 0x3FFF + 112 or x == 0) return x; + + if (u >> 127 != 0) { + y = x - math.f128_toint + math.f128_toint - x; + } else { + y = x + math.f128_toint - math.f128_toint - x; + } + + if (e <= 0x3FFF - 1) { + math.forceEval(y); + if (u >> 127 != 0) { + return -1.0; + } else { + return 0.0; + } + } else if (y > 0) { + return x + y - 1; + } else { + return x + y; + } +} + test "math.floor" { expect(floor(@as(f16, 1.3)) == floor16(1.3)); expect(floor(@as(f32, 1.3)) == floor32(1.3)); expect(floor(@as(f64, 1.3)) == floor64(1.3)); + expect(floor(@as(f128, 1.3)) == floor128(1.3)); } test "math.floor16" { @@ -146,6 +175,12 @@ test "math.floor64" { expect(floor64(0.2) == 0.0); } +test "math.floor128" { + expect(floor128(1.3) == 1.0); + expect(floor128(-1.3) == -2.0); + expect(floor128(0.2) == 0.0); +} + test "math.floor16.special" { expect(floor16(0.0) == 0.0); expect(floor16(-0.0) == -0.0); @@ -169,3 +204,11 @@ test "math.floor64.special" { expect(math.isNegativeInf(floor64(-math.inf(f64)))); expect(math.isNan(floor64(math.nan(f64)))); } + +test "math.floor128.special" { + expect(floor128(0.0) == 0.0); + expect(floor128(-0.0) == -0.0); + expect(math.isPositiveInf(floor128(math.inf(f128)))); + expect(math.isNegativeInf(floor128(-math.inf(f128)))); + expect(math.isNan(floor128(math.nan(f128)))); +} diff --git a/lib/std/math/frexp.zig b/lib/std/math/frexp.zig index cfdf9f838d..0e4558dc37 100644 --- a/lib/std/math/frexp.zig +++ b/lib/std/math/frexp.zig @@ -24,7 +24,7 @@ pub const frexp64_result = frexp_result(f64); /// - frexp(+-0) = +-0, 0 /// - frexp(+-inf) = +-inf, 0 /// - frexp(nan) = nan, undefined -pub fn frexp(x: var) frexp_result(@TypeOf(x)) { +pub fn frexp(x: anytype) frexp_result(@TypeOf(x)) { const T = @TypeOf(x); return switch (T) { f32 => frexp32(x), diff --git a/lib/std/math/ilogb.zig b/lib/std/math/ilogb.zig index 22e3fbaa97..748cf9ea0d 100644 --- a/lib/std/math/ilogb.zig +++ b/lib/std/math/ilogb.zig @@ -16,7 +16,7 @@ const minInt = std.math.minInt; /// - ilogb(+-inf) = maxInt(i32) /// - ilogb(0) = maxInt(i32) /// - ilogb(nan) = maxInt(i32) -pub fn ilogb(x: var) i32 { +pub fn ilogb(x: anytype) i32 { const T = @TypeOf(x); return switch (T) { f32 => ilogb32(x), diff --git a/lib/std/math/isfinite.zig b/lib/std/math/isfinite.zig index 26b3ce54a1..0681eae0b7 100644 --- a/lib/std/math/isfinite.zig +++ b/lib/std/math/isfinite.zig @@ -4,7 +4,7 @@ const expect = std.testing.expect; const maxInt = std.math.maxInt; /// Returns whether x is a finite value. -pub fn isFinite(x: var) bool { +pub fn isFinite(x: anytype) bool { const T = @TypeOf(x); switch (T) { f16 => { diff --git a/lib/std/math/isinf.zig b/lib/std/math/isinf.zig index 6eacab52ad..19357d89d1 100644 --- a/lib/std/math/isinf.zig +++ b/lib/std/math/isinf.zig @@ -4,7 +4,7 @@ const expect = std.testing.expect; const maxInt = std.math.maxInt; /// Returns whether x is an infinity, ignoring sign. -pub fn isInf(x: var) bool { +pub fn isInf(x: anytype) bool { const T = @TypeOf(x); switch (T) { f16 => { @@ -30,7 +30,7 @@ pub fn isInf(x: var) bool { } /// Returns whether x is an infinity with a positive sign. -pub fn isPositiveInf(x: var) bool { +pub fn isPositiveInf(x: anytype) bool { const T = @TypeOf(x); switch (T) { f16 => { @@ -52,7 +52,7 @@ pub fn isPositiveInf(x: var) bool { } /// Returns whether x is an infinity with a negative sign. -pub fn isNegativeInf(x: var) bool { +pub fn isNegativeInf(x: anytype) bool { const T = @TypeOf(x); switch (T) { f16 => { diff --git a/lib/std/math/isnan.zig b/lib/std/math/isnan.zig index ac865f0d0c..797c115d1d 100644 --- a/lib/std/math/isnan.zig +++ b/lib/std/math/isnan.zig @@ -4,12 +4,12 @@ const expect = std.testing.expect; const maxInt = std.math.maxInt; /// Returns whether x is a nan. -pub fn isNan(x: var) bool { +pub fn isNan(x: anytype) bool { return x != x; } /// Returns whether x is a signalling nan. -pub fn isSignalNan(x: var) bool { +pub fn isSignalNan(x: anytype) bool { // Note: A signalling nan is identical to a standard nan right now but may have a different bit // representation in the future when required. return isNan(x); diff --git a/lib/std/math/isnormal.zig b/lib/std/math/isnormal.zig index 917b4ebfcf..a3144f2784 100644 --- a/lib/std/math/isnormal.zig +++ b/lib/std/math/isnormal.zig @@ -4,7 +4,7 @@ const expect = std.testing.expect; const maxInt = std.math.maxInt; // Returns whether x has a normalized representation (i.e. integer part of mantissa is 1). -pub fn isNormal(x: var) bool { +pub fn isNormal(x: anytype) bool { const T = @TypeOf(x); switch (T) { f16 => { diff --git a/lib/std/math/ln.zig b/lib/std/math/ln.zig index 555a786907..99e54c4cc7 100644 --- a/lib/std/math/ln.zig +++ b/lib/std/math/ln.zig @@ -15,7 +15,7 @@ const expect = std.testing.expect; /// - ln(0) = -inf /// - ln(x) = nan if x < 0 /// - ln(nan) = nan -pub fn ln(x: var) @TypeOf(x) { +pub fn ln(x: anytype) @TypeOf(x) { const T = @TypeOf(x); switch (@typeInfo(T)) { .ComptimeFloat => { diff --git a/lib/std/math/log10.zig b/lib/std/math/log10.zig index 7367af28c6..e55bd8c1e8 100644 --- a/lib/std/math/log10.zig +++ b/lib/std/math/log10.zig @@ -16,7 +16,7 @@ const maxInt = std.math.maxInt; /// - log10(0) = -inf /// - log10(x) = nan if x < 0 /// - log10(nan) = nan -pub fn log10(x: var) @TypeOf(x) { +pub fn log10(x: anytype) @TypeOf(x) { const T = @TypeOf(x); switch (@typeInfo(T)) { .ComptimeFloat => { diff --git a/lib/std/math/log1p.zig b/lib/std/math/log1p.zig index 5e92cfdea3..e24ba8d84d 100644 --- a/lib/std/math/log1p.zig +++ b/lib/std/math/log1p.zig @@ -17,7 +17,7 @@ const expect = std.testing.expect; /// - log1p(-1) = -inf /// - log1p(x) = nan if x < -1 /// - log1p(nan) = nan -pub fn log1p(x: var) @TypeOf(x) { +pub fn log1p(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => log1p_32(x), diff --git a/lib/std/math/log2.zig b/lib/std/math/log2.zig index 54f8bc2baa..95d06a2b60 100644 --- a/lib/std/math/log2.zig +++ b/lib/std/math/log2.zig @@ -16,7 +16,7 @@ const maxInt = std.math.maxInt; /// - log2(0) = -inf /// - log2(x) = nan if x < 0 /// - log2(nan) = nan -pub fn log2(x: var) @TypeOf(x) { +pub fn log2(x: anytype) @TypeOf(x) { const T = @TypeOf(x); switch (@typeInfo(T)) { .ComptimeFloat => { diff --git a/lib/std/math/modf.zig b/lib/std/math/modf.zig index 6fd89e3dda..5ab5318a79 100644 --- a/lib/std/math/modf.zig +++ b/lib/std/math/modf.zig @@ -24,7 +24,7 @@ pub const modf64_result = modf_result(f64); /// Special Cases: /// - modf(+-inf) = +-inf, nan /// - modf(nan) = nan, nan -pub fn modf(x: var) modf_result(@TypeOf(x)) { +pub fn modf(x: anytype) modf_result(@TypeOf(x)) { const T = @TypeOf(x); return switch (T) { f32 => modf32(x), diff --git a/lib/std/math/round.zig b/lib/std/math/round.zig index dceb3ed770..854adee4ba 100644 --- a/lib/std/math/round.zig +++ b/lib/std/math/round.zig @@ -15,11 +15,12 @@ const math = std.math; /// - round(+-0) = +-0 /// - round(+-inf) = +-inf /// - round(nan) = nan -pub fn round(x: var) @TypeOf(x) { +pub fn round(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => round32(x), f64 => round64(x), + f128 => round128(x), else => @compileError("round not implemented for " ++ @typeName(T)), }; } @@ -90,9 +91,43 @@ fn round64(x_: f64) f64 { } } +fn round128(x_: f128) f128 { + var x = x_; + const u = @bitCast(u128, x); + const e = (u >> 112) & 0x7FFF; + var y: f128 = undefined; + + if (e >= 0x3FFF + 112) { + return x; + } + if (u >> 127 != 0) { + x = -x; + } + if (e < 0x3FFF - 1) { + math.forceEval(x + math.f64_toint); + return 0 * @bitCast(f128, u); + } + + y = x + math.f128_toint - math.f128_toint - x; + if (y > 0.5) { + y = y + x - 1; + } else if (y <= -0.5) { + y = y + x + 1; + } else { + y = y + x; + } + + if (u >> 127 != 0) { + return -y; + } else { + return y; + } +} + test "math.round" { expect(round(@as(f32, 1.3)) == round32(1.3)); expect(round(@as(f64, 1.3)) == round64(1.3)); + expect(round(@as(f128, 1.3)) == round128(1.3)); } test "math.round32" { @@ -109,6 +144,13 @@ test "math.round64" { expect(round64(1.8) == 2.0); } +test "math.round128" { + expect(round128(1.3) == 1.0); + expect(round128(-1.3) == -1.0); + expect(round128(0.2) == 0.0); + expect(round128(1.8) == 2.0); +} + test "math.round32.special" { expect(round32(0.0) == 0.0); expect(round32(-0.0) == -0.0); @@ -124,3 +166,11 @@ test "math.round64.special" { expect(math.isNegativeInf(round64(-math.inf(f64)))); expect(math.isNan(round64(math.nan(f64)))); } + +test "math.round128.special" { + expect(round128(0.0) == 0.0); + expect(round128(-0.0) == -0.0); + expect(math.isPositiveInf(round128(math.inf(f128)))); + expect(math.isNegativeInf(round128(-math.inf(f128)))); + expect(math.isNan(round128(math.nan(f128)))); +} diff --git a/lib/std/math/scalbn.zig b/lib/std/math/scalbn.zig index bab109f334..71a8110ce7 100644 --- a/lib/std/math/scalbn.zig +++ b/lib/std/math/scalbn.zig @@ -9,7 +9,7 @@ const math = std.math; const expect = std.testing.expect; /// Returns x * 2^n. -pub fn scalbn(x: var, n: i32) @TypeOf(x) { +pub fn scalbn(x: anytype, n: i32) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => scalbn32(x, n), diff --git a/lib/std/math/signbit.zig b/lib/std/math/signbit.zig index 9cb62b5042..49397f7bd4 100644 --- a/lib/std/math/signbit.zig +++ b/lib/std/math/signbit.zig @@ -3,7 +3,7 @@ const math = std.math; const expect = std.testing.expect; /// Returns whether x is negative or negative 0. -pub fn signbit(x: var) bool { +pub fn signbit(x: anytype) bool { const T = @TypeOf(x); return switch (T) { f16 => signbit16(x), diff --git a/lib/std/math/sin.zig b/lib/std/math/sin.zig index e88f5eeeaf..df3b294ca6 100644 --- a/lib/std/math/sin.zig +++ b/lib/std/math/sin.zig @@ -14,7 +14,7 @@ const expect = std.testing.expect; /// - sin(+-0) = +-0 /// - sin(+-inf) = nan /// - sin(nan) = nan -pub fn sin(x: var) @TypeOf(x) { +pub fn sin(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => sin_(T, x), diff --git a/lib/std/math/sinh.zig b/lib/std/math/sinh.zig index 0e2cb5a3d5..26e0e05f38 100644 --- a/lib/std/math/sinh.zig +++ b/lib/std/math/sinh.zig @@ -17,7 +17,7 @@ const maxInt = std.math.maxInt; /// - sinh(+-0) = +-0 /// - sinh(+-inf) = +-inf /// - sinh(nan) = nan -pub fn sinh(x: var) @TypeOf(x) { +pub fn sinh(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => sinh32(x), diff --git a/lib/std/math/sqrt.zig b/lib/std/math/sqrt.zig index 097b0152f7..2f0d251432 100644 --- a/lib/std/math/sqrt.zig +++ b/lib/std/math/sqrt.zig @@ -13,7 +13,7 @@ const maxInt = std.math.maxInt; /// - sqrt(x) = nan if x < 0 /// - sqrt(nan) = nan /// TODO Decide if all this logic should be implemented directly in the @sqrt bultin function. -pub fn sqrt(x: var) Sqrt(@TypeOf(x)) { +pub fn sqrt(x: anytype) Sqrt(@TypeOf(x)) { const T = @TypeOf(x); switch (@typeInfo(T)) { .Float, .ComptimeFloat => return @sqrt(x), diff --git a/lib/std/math/tan.zig b/lib/std/math/tan.zig index 86f473f448..2cd5a407df 100644 --- a/lib/std/math/tan.zig +++ b/lib/std/math/tan.zig @@ -14,7 +14,7 @@ const expect = std.testing.expect; /// - tan(+-0) = +-0 /// - tan(+-inf) = nan /// - tan(nan) = nan -pub fn tan(x: var) @TypeOf(x) { +pub fn tan(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => tan_(f32, x), diff --git a/lib/std/math/tanh.zig b/lib/std/math/tanh.zig index 1cad399729..7697db5271 100644 --- a/lib/std/math/tanh.zig +++ b/lib/std/math/tanh.zig @@ -17,7 +17,7 @@ const maxInt = std.math.maxInt; /// - sinh(+-0) = +-0 /// - sinh(+-inf) = +-1 /// - sinh(nan) = nan -pub fn tanh(x: var) @TypeOf(x) { +pub fn tanh(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => tanh32(x), diff --git a/lib/std/math/trunc.zig b/lib/std/math/trunc.zig index b70f0c6be3..df24b77111 100644 --- a/lib/std/math/trunc.zig +++ b/lib/std/math/trunc.zig @@ -15,11 +15,12 @@ const maxInt = std.math.maxInt; /// - trunc(+-0) = +-0 /// - trunc(+-inf) = +-inf /// - trunc(nan) = nan -pub fn trunc(x: var) @TypeOf(x) { +pub fn trunc(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f32 => trunc32(x), f64 => trunc64(x), + f128 => trunc128(x), else => @compileError("trunc not implemented for " ++ @typeName(T)), }; } @@ -66,9 +67,31 @@ fn trunc64(x: f64) f64 { } } +fn trunc128(x: f128) f128 { + const u = @bitCast(u128, x); + var e = @intCast(i32, ((u >> 112) & 0x7FFF)) - 0x3FFF + 16; + var m: u128 = undefined; + + if (e >= 112 + 16) { + return x; + } + if (e < 16) { + e = 1; + } + + m = @as(u128, maxInt(u128)) >> @intCast(u7, e); + if (u & m == 0) { + return x; + } else { + math.forceEval(x + 0x1p120); + return @bitCast(f128, u & ~m); + } +} + test "math.trunc" { expect(trunc(@as(f32, 1.3)) == trunc32(1.3)); expect(trunc(@as(f64, 1.3)) == trunc64(1.3)); + expect(trunc(@as(f128, 1.3)) == trunc128(1.3)); } test "math.trunc32" { @@ -83,6 +106,12 @@ test "math.trunc64" { expect(trunc64(0.2) == 0.0); } +test "math.trunc128" { + expect(trunc128(1.3) == 1.0); + expect(trunc128(-1.3) == -1.0); + expect(trunc128(0.2) == 0.0); +} + test "math.trunc32.special" { expect(trunc32(0.0) == 0.0); // 0x3F800000 expect(trunc32(-0.0) == -0.0); @@ -98,3 +127,11 @@ test "math.trunc64.special" { expect(math.isNegativeInf(trunc64(-math.inf(f64)))); expect(math.isNan(trunc64(math.nan(f64)))); } + +test "math.trunc128.special" { + expect(trunc128(0.0) == 0.0); + expect(trunc128(-0.0) == -0.0); + expect(math.isPositiveInf(trunc128(math.inf(f128)))); + expect(math.isNegativeInf(trunc128(-math.inf(f128)))); + expect(math.isNan(trunc128(math.nan(f128)))); +} |
