| author | |
| committer | |
| log | ad10c7600793547393848528e7d4a608d9fde59e |
| tree | 09df3c266a372562c615bca323aca308dac29523 |
| parent | 61161132b63d641657df3f099511e2fa5062d0d1 |
| signature |
Additionally, use `std.math.pi / 4.0` for `pi/4` in `trig.zig`
instead of hardcoding the value.5 files changed, 146 insertions(+), 145 deletions(-)
lib/compiler_rt/cos.zig+35-35| ... | @@ -20,11 +20,11 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; | ... | @@ -20,11 +20,11 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 20 | const ld = @import("long_double.zig"); | 20 | const ld = @import("long_double.zig"); |
| 21 | 21 | ||
| 22 | comptime { | 22 | comptime { |
| 23 | symbol(&__cosh, "__cosh"); | 23 | symbol(&cosh, "__cosh"); |
| 24 | symbol(&cosl, "__cosl"); | 24 | symbol(&cosl, "__cosl"); |
| 25 | symbol(&cosf, "cosf"); | 25 | symbol(&cosf, "cosf"); |
| 26 | symbol(&cos, "cos"); | 26 | symbol(&cos, "cos"); |
| 27 | symbol(&__cosx, "__cosx"); | 27 | symbol(&cosx, "__cosx"); |
| 28 | if (compiler_rt.want_ppc_abi) { | 28 | if (compiler_rt.want_ppc_abi) { |
| 29 | symbol(&cosq, "cosf128"); | 29 | symbol(&cosq, "cosf128"); |
| 30 | } | 30 | } |
| ... | @@ -32,7 +32,7 @@ comptime { | ... | @@ -32,7 +32,7 @@ comptime { |
| 32 | symbol(&cosl, "cosl"); | 32 | symbol(&cosl, "cosl"); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | pub fn __cosh(a: f16) callconv(.c) f16 { | 35 | pub fn cosh(a: f16) callconv(.c) f16 { |
| 36 | // TODO: more efficient implementation | 36 | // TODO: more efficient implementation |
| 37 | return @floatCast(cosf(a)); | 37 | return @floatCast(cosf(a)); |
| 38 | } | 38 | } |
| ... | @@ -54,27 +54,27 @@ pub fn cosf(x: f32) callconv(.c) f32 { | ... | @@ -54,27 +54,27 @@ pub fn cosf(x: f32) callconv(.c) f32 { |
| 54 | if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120); | 54 | if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120); |
| 55 | return 1.0; | 55 | return 1.0; |
| 56 | } | 56 | } |
| 57 | return trig.__cosdf(x); | 57 | return trig.cosdf(x); |
| 58 | } | 58 | } |
| 59 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 | 59 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 |
| 60 | if (ix > 0x4016cbe3) { // |x| ~> 3*pi/4 | 60 | if (ix > 0x4016cbe3) { // |x| ~> 3*pi/4 |
| 61 | return -trig.__cosdf(if (sign) x + c2pio2 else x - c2pio2); | 61 | return -trig.cosdf(if (sign) x + c2pio2 else x - c2pio2); |
| 62 | } else { | 62 | } else { |
| 63 | if (sign) { | 63 | if (sign) { |
| 64 | return trig.__sindf(x + c1pio2); | 64 | return trig.sindf(x + c1pio2); |
| 65 | } else { | 65 | } else { |
| 66 | return trig.__sindf(c1pio2 - x); | 66 | return trig.sindf(c1pio2 - x); |
| 67 | } | 67 | } |
| 68 | } | 68 | } |
| 69 | } | 69 | } |
| 70 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 | 70 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 |
| 71 | if (ix > 0x40afeddf) { // |x| ~> 7*pi/4 | 71 | if (ix > 0x40afeddf) { // |x| ~> 7*pi/4 |
| 72 | return trig.__cosdf(if (sign) x + c4pio2 else x - c4pio2); | 72 | return trig.cosdf(if (sign) x + c4pio2 else x - c4pio2); |
| 73 | } else { | 73 | } else { |
| 74 | if (sign) { | 74 | if (sign) { |
| 75 | return trig.__sindf(-x - c3pio2); | 75 | return trig.sindf(-x - c3pio2); |
| 76 | } else { | 76 | } else { |
| 77 | return trig.__sindf(x - c3pio2); | 77 | return trig.sindf(x - c3pio2); |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | } | 80 | } |
| ... | @@ -87,10 +87,10 @@ pub fn cosf(x: f32) callconv(.c) f32 { | ... | @@ -87,10 +87,10 @@ pub fn cosf(x: f32) callconv(.c) f32 { |
| 87 | var y: f64 = undefined; | 87 | var y: f64 = undefined; |
| 88 | const n = rem_pio2f(x, &y); | 88 | const n = rem_pio2f(x, &y); |
| 89 | return switch (n & 3) { | 89 | return switch (n & 3) { |
| 90 | 0 => trig.__cosdf(y), | 90 | 0 => trig.cosdf(y), |
| 91 | 1 => trig.__sindf(-y), | 91 | 1 => trig.sindf(-y), |
| 92 | 2 => -trig.__cosdf(y), | 92 | 2 => -trig.cosdf(y), |
| 93 | else => trig.__sindf(y), | 93 | else => trig.sindf(y), |
| 94 | }; | 94 | }; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| ... | @@ -105,7 +105,7 @@ pub fn cos(x: f64) callconv(.c) f64 { | ... | @@ -105,7 +105,7 @@ pub fn cos(x: f64) callconv(.c) f64 { |
| 105 | if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120); | 105 | if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120); |
| 106 | return 1.0; | 106 | return 1.0; |
| 107 | } | 107 | } |
| 108 | return trig.__cos(x, 0); | 108 | return trig.cos(x, 0); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | // cos(Inf or NaN) is NaN | 111 | // cos(Inf or NaN) is NaN |
| ... | @@ -116,10 +116,10 @@ pub fn cos(x: f64) callconv(.c) f64 { | ... | @@ -116,10 +116,10 @@ pub fn cos(x: f64) callconv(.c) f64 { |
| 116 | var y: [2]f64 = undefined; | 116 | var y: [2]f64 = undefined; |
| 117 | const n = rem_pio2(x, &y); | 117 | const n = rem_pio2(x, &y); |
| 118 | return switch (n & 3) { | 118 | return switch (n & 3) { |
| 119 | 0 => trig.__cos(y[0], y[1]), | 119 | 0 => trig.cos(y[0], y[1]), |
| 120 | 1 => -trig.__sin(y[0], y[1], 1), | 120 | 1 => -trig.sin(y[0], y[1], 1), |
| 121 | 2 => -trig.__cos(y[0], y[1]), | 121 | 2 => -trig.cos(y[0], y[1]), |
| 122 | else => trig.__sin(y[0], y[1], 1), | 122 | else => trig.sin(y[0], y[1], 1), |
| 123 | }; | 123 | }; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| ... | @@ -134,20 +134,20 @@ fn coslGeneric(comptime T: type, x: T) T { | ... | @@ -134,20 +134,20 @@ fn coslGeneric(comptime T: type, x: T) T { |
| 134 | // raise inexact if x!=0 | 134 | // raise inexact if x!=0 |
| 135 | return 1.0 + x; | 135 | return 1.0 + x; |
| 136 | } | 136 | } |
| 137 | return trig.__cosl(T, x, 0.0); | 137 | return trig.cosl(T, x, 0.0); |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | var y: [2]T = undefined; | 140 | var y: [2]T = undefined; |
| 141 | const n = rem_pio2l(T, x, &y); | 141 | const n = rem_pio2l(T, x, &y); |
| 142 | return switch (n & 3) { | 142 | return switch (n & 3) { |
| 143 | 0 => trig.__cosl(T, y[0], y[1]), | 143 | 0 => trig.cosl(T, y[0], y[1]), |
| 144 | 1 => -trig.__sinl(T, y[0], y[1], 1), | 144 | 1 => -trig.sinl(T, y[0], y[1], 1), |
| 145 | 2 => -trig.__cosl(T, y[0], y[1]), | 145 | 2 => -trig.cosl(T, y[0], y[1]), |
| 146 | else => trig.__sinl(T, y[0], y[1], 1), | 146 | else => trig.sinl(T, y[0], y[1], 1), |
| 147 | }; | 147 | }; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | pub fn __cosx(x: f80) callconv(.c) f80 { | 150 | pub fn cosx(x: f80) callconv(.c) f80 { |
| 151 | return coslGeneric(f80, x); | 151 | return coslGeneric(f80, x); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| ... | @@ -157,10 +157,10 @@ pub fn cosq(x: f128) callconv(.c) f128 { | ... | @@ -157,10 +157,10 @@ pub fn cosq(x: f128) callconv(.c) f128 { |
| 157 | 157 | ||
| 158 | pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble { | 158 | pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble { |
| 159 | switch (@typeInfo(c_longdouble).float.bits) { | 159 | switch (@typeInfo(c_longdouble).float.bits) { |
| 160 | 16 => return __cosh(x), | 160 | 16 => return cosh(x), |
| 161 | 32 => return cosf(x), | 161 | 32 => return cosf(x), |
| 162 | 64 => return cos(x), | 162 | 64 => return cos(x), |
| 163 | 80 => return __cosx(x), | 163 | 80 => return cosx(x), |
| 164 | 128 => return cosq(x), | 164 | 128 => return cosq(x), |
| 165 | else => @compileError("unreachable"), | 165 | else => @compileError("unreachable"), |
| 166 | } | 166 | } |
| ... | @@ -170,7 +170,7 @@ fn testCosSpecial(comptime T: type) !void { | ... | @@ -170,7 +170,7 @@ fn testCosSpecial(comptime T: type) !void { |
| 170 | const f = switch (T) { | 170 | const f = switch (T) { |
| 171 | f32 => cosf, | 171 | f32 => cosf, |
| 172 | f64 => cos, | 172 | f64 => cos, |
| 173 | f80 => __cosx, | 173 | f80 => cosx, |
| 174 | f128 => cosq, | 174 | f128 => cosq, |
| 175 | else => @compileError("unimplemented"), | 175 | else => @compileError("unimplemented"), |
| 176 | }; | 176 | }; |
| ... | @@ -214,13 +214,13 @@ test "cos64.special" { | ... | @@ -214,13 +214,13 @@ test "cos64.special" { |
| 214 | 214 | ||
| 215 | test "cos80.normal" { | 215 | test "cos80.normal" { |
| 216 | const epsilon = math.floatEps(f80); | 216 | const epsilon = math.floatEps(f80); |
| 217 | try expectApproxEqAbs(@as(f80, 1.0), __cosx(0.0), epsilon); | 217 | try expectApproxEqAbs(@as(f80, 1.0), cosx(0.0), epsilon); |
| 218 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), __cosx(0.2), epsilon); | 218 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cosx(0.2), epsilon); |
| 219 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), __cosx(0.8923), epsilon); | 219 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cosx(0.8923), epsilon); |
| 220 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), __cosx(1.5), epsilon); | 220 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(1.5), epsilon); |
| 221 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), __cosx(-1.5), epsilon); | 221 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(-1.5), epsilon); |
| 222 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), __cosx(37.45), epsilon); | 222 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cosx(37.45), epsilon); |
| 223 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), __cosx(89.123), epsilon); | 223 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cosx(89.123), epsilon); |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | test "cos80.special" { | 226 | test "cos80.special" { |
lib/compiler_rt/sin.zig+35-35| ... | @@ -20,11 +20,11 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; | ... | @@ -20,11 +20,11 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 20 | const ld = @import("long_double.zig"); | 20 | const ld = @import("long_double.zig"); |
| 21 | 21 | ||
| 22 | comptime { | 22 | comptime { |
| 23 | symbol(&__sinh, "__sinh"); | 23 | symbol(&sinh, "__sinh"); |
| 24 | symbol(&sinl, "__sinl"); | 24 | symbol(&sinl, "__sinl"); |
| 25 | symbol(&sinf, "sinf"); | 25 | symbol(&sinf, "sinf"); |
| 26 | symbol(&sin, "sin"); | 26 | symbol(&sin, "sin"); |
| 27 | symbol(&__sinx, "__sinx"); | 27 | symbol(&sinx, "__sinx"); |
| 28 | if (compiler_rt.want_ppc_abi) { | 28 | if (compiler_rt.want_ppc_abi) { |
| 29 | symbol(&sinq, "sinf128"); | 29 | symbol(&sinq, "sinf128"); |
| 30 | } | 30 | } |
| ... | @@ -32,7 +32,7 @@ comptime { | ... | @@ -32,7 +32,7 @@ comptime { |
| 32 | symbol(&sinl, "sinl"); | 32 | symbol(&sinl, "sinl"); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | pub fn __sinh(x: f16) callconv(.c) f16 { | 35 | pub fn sinh(x: f16) callconv(.c) f16 { |
| 36 | // TODO: more efficient implementation | 36 | // TODO: more efficient implementation |
| 37 | return @floatCast(sinf(x)); | 37 | return @floatCast(sinf(x)); |
| 38 | } | 38 | } |
| ... | @@ -60,27 +60,27 @@ pub fn sinf(x: f32) callconv(.c) f32 { | ... | @@ -60,27 +60,27 @@ pub fn sinf(x: f32) callconv(.c) f32 { |
| 60 | } | 60 | } |
| 61 | return x; | 61 | return x; |
| 62 | } | 62 | } |
| 63 | return trig.__sindf(x); | 63 | return trig.sindf(x); |
| 64 | } | 64 | } |
| 65 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 | 65 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 |
| 66 | if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4 | 66 | if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4 |
| 67 | if (sign) { | 67 | if (sign) { |
| 68 | return -trig.__cosdf(x + s1pio2); | 68 | return -trig.cosdf(x + s1pio2); |
| 69 | } else { | 69 | } else { |
| 70 | return trig.__cosdf(x - s1pio2); | 70 | return trig.cosdf(x - s1pio2); |
| 71 | } | 71 | } |
| 72 | } | 72 | } |
| 73 | return trig.__sindf(if (sign) -(x + s2pio2) else -(x - s2pio2)); | 73 | return trig.sindf(if (sign) -(x + s2pio2) else -(x - s2pio2)); |
| 74 | } | 74 | } |
| 75 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 | 75 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 |
| 76 | if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4 | 76 | if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4 |
| 77 | if (sign) { | 77 | if (sign) { |
| 78 | return trig.__cosdf(x + s3pio2); | 78 | return trig.cosdf(x + s3pio2); |
| 79 | } else { | 79 | } else { |
| 80 | return -trig.__cosdf(x - s3pio2); | 80 | return -trig.cosdf(x - s3pio2); |
| 81 | } | 81 | } |
| 82 | } | 82 | } |
| 83 | return trig.__sindf(if (sign) x + s4pio2 else x - s4pio2); | 83 | return trig.sindf(if (sign) x + s4pio2 else x - s4pio2); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | // sin(Inf or NaN) is NaN | 86 | // sin(Inf or NaN) is NaN |
| ... | @@ -91,10 +91,10 @@ pub fn sinf(x: f32) callconv(.c) f32 { | ... | @@ -91,10 +91,10 @@ pub fn sinf(x: f32) callconv(.c) f32 { |
| 91 | var y: f64 = undefined; | 91 | var y: f64 = undefined; |
| 92 | const n = rem_pio2f(x, &y); | 92 | const n = rem_pio2f(x, &y); |
| 93 | return switch (n & 3) { | 93 | return switch (n & 3) { |
| 94 | 0 => trig.__sindf(y), | 94 | 0 => trig.sindf(y), |
| 95 | 1 => trig.__cosdf(y), | 95 | 1 => trig.cosdf(y), |
| 96 | 2 => trig.__sindf(-y), | 96 | 2 => trig.sindf(-y), |
| 97 | else => -trig.__cosdf(y), | 97 | else => -trig.cosdf(y), |
| 98 | }; | 98 | }; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| ... | @@ -115,7 +115,7 @@ pub fn sin(x: f64) callconv(.c) f64 { | ... | @@ -115,7 +115,7 @@ pub fn sin(x: f64) callconv(.c) f64 { |
| 115 | } | 115 | } |
| 116 | return x; | 116 | return x; |
| 117 | } | 117 | } |
| 118 | return trig.__sin(x, 0.0, 0); | 118 | return trig.sin(x, 0.0, 0); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | // sin(Inf or NaN) is NaN | 121 | // sin(Inf or NaN) is NaN |
| ... | @@ -126,10 +126,10 @@ pub fn sin(x: f64) callconv(.c) f64 { | ... | @@ -126,10 +126,10 @@ pub fn sin(x: f64) callconv(.c) f64 { |
| 126 | var y: [2]f64 = undefined; | 126 | var y: [2]f64 = undefined; |
| 127 | const n = rem_pio2(x, &y); | 127 | const n = rem_pio2(x, &y); |
| 128 | return switch (n & 3) { | 128 | return switch (n & 3) { |
| 129 | 0 => trig.__sin(y[0], y[1], 1), | 129 | 0 => trig.sin(y[0], y[1], 1), |
| 130 | 1 => trig.__cos(y[0], y[1]), | 130 | 1 => trig.cos(y[0], y[1]), |
| 131 | 2 => -trig.__sin(y[0], y[1], 1), | 131 | 2 => -trig.sin(y[0], y[1], 1), |
| 132 | else => -trig.__cos(y[0], y[1]), | 132 | else => -trig.cos(y[0], y[1]), |
| 133 | }; | 133 | }; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| ... | @@ -147,20 +147,20 @@ fn sinlGeneric(comptime T: type, x: T) T { | ... | @@ -147,20 +147,20 @@ fn sinlGeneric(comptime T: type, x: T) T { |
| 147 | } | 147 | } |
| 148 | return x; | 148 | return x; |
| 149 | } | 149 | } |
| 150 | return trig.__sinl(T, x, 0.0, 0); | 150 | return trig.sinl(T, x, 0.0, 0); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | var y: [2]T = undefined; | 153 | var y: [2]T = undefined; |
| 154 | const n = rem_pio2l(T, x, &y); | 154 | const n = rem_pio2l(T, x, &y); |
| 155 | return switch (n & 3) { | 155 | return switch (n & 3) { |
| 156 | 0 => trig.__sinl(T, y[0], y[1], 1), | 156 | 0 => trig.sinl(T, y[0], y[1], 1), |
| 157 | 1 => trig.__cosl(T, y[0], y[1]), | 157 | 1 => trig.cosl(T, y[0], y[1]), |
| 158 | 2 => -trig.__sinl(T, y[0], y[1], 1), | 158 | 2 => -trig.sinl(T, y[0], y[1], 1), |
| 159 | else => -trig.__cosl(T, y[0], y[1]), | 159 | else => -trig.cosl(T, y[0], y[1]), |
| 160 | }; | 160 | }; |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | pub fn __sinx(x: f80) callconv(.c) f80 { | 163 | pub fn sinx(x: f80) callconv(.c) f80 { |
| 164 | return sinlGeneric(f80, x); | 164 | return sinlGeneric(f80, x); |
| 165 | } | 165 | } |
| 166 | 166 | ||
| ... | @@ -170,10 +170,10 @@ pub fn sinq(x: f128) callconv(.c) f128 { | ... | @@ -170,10 +170,10 @@ pub fn sinq(x: f128) callconv(.c) f128 { |
| 170 | 170 | ||
| 171 | pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble { | 171 | pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble { |
| 172 | switch (@typeInfo(c_longdouble).float.bits) { | 172 | switch (@typeInfo(c_longdouble).float.bits) { |
| 173 | 16 => return __sinh(x), | 173 | 16 => return sinh(x), |
| 174 | 32 => return sinf(x), | 174 | 32 => return sinf(x), |
| 175 | 64 => return sin(x), | 175 | 64 => return sin(x), |
| 176 | 80 => return __sinx(x), | 176 | 80 => return sinx(x), |
| 177 | 128 => return sinq(x), | 177 | 128 => return sinq(x), |
| 178 | else => @compileError("unreachable"), | 178 | else => @compileError("unreachable"), |
| 179 | } | 179 | } |
| ... | @@ -183,7 +183,7 @@ fn testSinSpecial(comptime T: type) !void { | ... | @@ -183,7 +183,7 @@ fn testSinSpecial(comptime T: type) !void { |
| 183 | const f = switch (T) { | 183 | const f = switch (T) { |
| 184 | f32 => sinf, | 184 | f32 => sinf, |
| 185 | f64 => sin, | 185 | f64 => sin, |
| 186 | f80 => __sinx, | 186 | f80 => sinx, |
| 187 | f128 => sinq, | 187 | f128 => sinq, |
| 188 | else => @compileError("unimplemented"), | 188 | else => @compileError("unimplemented"), |
| 189 | }; | 189 | }; |
| ... | @@ -227,13 +227,13 @@ test "sin64.special" { | ... | @@ -227,13 +227,13 @@ test "sin64.special" { |
| 227 | 227 | ||
| 228 | test "sin80.normal" { | 228 | test "sin80.normal" { |
| 229 | const epsilon = math.floatEps(f80); | 229 | const epsilon = math.floatEps(f80); |
| 230 | try expectApproxEqAbs(@as(f80, 0.0), __sinx(0.0), epsilon); | 230 | try expectApproxEqAbs(@as(f80, 0.0), sinx(0.0), epsilon); |
| 231 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), __sinx(0.2), epsilon); | 231 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sinx(0.2), epsilon); |
| 232 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), __sinx(0.8923), epsilon); | 232 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sinx(0.8923), epsilon); |
| 233 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), __sinx(1.5), epsilon); | 233 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sinx(1.5), epsilon); |
| 234 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), __sinx(-1.5), epsilon); | 234 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sinx(-1.5), epsilon); |
| 235 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), __sinx(37.45), epsilon); | 235 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sinx(37.45), epsilon); |
| 236 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), __sinx(89.123), epsilon); | 236 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sinx(89.123), epsilon); |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | test "sin80.special" { | 239 | test "sin80.special" { |
lib/compiler_rt/sincos.zig+38-38| ... | @@ -14,10 +14,10 @@ const compiler_rt = @import("../compiler_rt.zig"); | ... | @@ -14,10 +14,10 @@ const compiler_rt = @import("../compiler_rt.zig"); |
| 14 | const symbol = compiler_rt.symbol; | 14 | const symbol = compiler_rt.symbol; |
| 15 | 15 | ||
| 16 | comptime { | 16 | comptime { |
| 17 | symbol(&__sincosh, "__sincosh"); | 17 | symbol(&sincosh, "__sincosh"); |
| 18 | symbol(&sincosf, "sincosf"); | 18 | symbol(&sincosf, "sincosf"); |
| 19 | symbol(&sincos, "sincos"); | 19 | symbol(&sincos, "sincos"); |
| 20 | symbol(&__sincosx, "__sincosx"); | 20 | symbol(&sincosx, "__sincosx"); |
| 21 | if (compiler_rt.want_ppc_abi) { | 21 | if (compiler_rt.want_ppc_abi) { |
| 22 | symbol(&sincosq, "sincosf128"); | 22 | symbol(&sincosq, "sincosf128"); |
| 23 | } | 23 | } |
| ... | @@ -25,7 +25,7 @@ comptime { | ... | @@ -25,7 +25,7 @@ comptime { |
| 25 | symbol(&sincosl, "sincosl"); | 25 | symbol(&sincosl, "sincosl"); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | pub fn __sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void { | 28 | pub fn sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void { |
| 29 | // TODO: more efficient implementation | 29 | // TODO: more efficient implementation |
| 30 | var big_sin: f32 = undefined; | 30 | var big_sin: f32 = undefined; |
| 31 | var big_cos: f32 = undefined; | 31 | var big_cos: f32 = undefined; |
| ... | @@ -60,8 +60,8 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | ... | @@ -60,8 +60,8 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 60 | r_cos.* = 1.0; | 60 | r_cos.* = 1.0; |
| 61 | return; | 61 | return; |
| 62 | } | 62 | } |
| 63 | r_sin.* = trig.__sindf(x); | 63 | r_sin.* = trig.sindf(x); |
| 64 | r_cos.* = trig.__cosdf(x); | 64 | r_cos.* = trig.cosdf(x); |
| 65 | return; | 65 | return; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| ... | @@ -70,17 +70,17 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | ... | @@ -70,17 +70,17 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 70 | // |x| ~<= 3pi/4 | 70 | // |x| ~<= 3pi/4 |
| 71 | if (ix <= 0x4016cbe3) { | 71 | if (ix <= 0x4016cbe3) { |
| 72 | if (sign) { | 72 | if (sign) { |
| 73 | r_sin.* = -trig.__cosdf(x + sc1pio2); | 73 | r_sin.* = -trig.cosdf(x + sc1pio2); |
| 74 | r_cos.* = trig.__sindf(x + sc1pio2); | 74 | r_cos.* = trig.sindf(x + sc1pio2); |
| 75 | } else { | 75 | } else { |
| 76 | r_sin.* = trig.__cosdf(sc1pio2 - x); | 76 | r_sin.* = trig.cosdf(sc1pio2 - x); |
| 77 | r_cos.* = trig.__sindf(sc1pio2 - x); | 77 | r_cos.* = trig.sindf(sc1pio2 - x); |
| 78 | } | 78 | } |
| 79 | return; | 79 | return; |
| 80 | } | 80 | } |
| 81 | // -sin(x+c) is not correct if x+c could be 0: -0 vs +0 | 81 | // -sin(x+c) is not correct if x+c could be 0: -0 vs +0 |
| 82 | r_sin.* = -trig.__sindf(if (sign) x + sc2pio2 else x - sc2pio2); | 82 | r_sin.* = -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2); |
| 83 | r_cos.* = -trig.__cosdf(if (sign) x + sc2pio2 else x - sc2pio2); | 83 | r_cos.* = -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2); |
| 84 | return; | 84 | return; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| ... | @@ -89,16 +89,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | ... | @@ -89,16 +89,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 89 | // |x| ~<= 7*pi/4 | 89 | // |x| ~<= 7*pi/4 |
| 90 | if (ix <= 0x40afeddf) { | 90 | if (ix <= 0x40afeddf) { |
| 91 | if (sign) { | 91 | if (sign) { |
| 92 | r_sin.* = trig.__cosdf(x + sc3pio2); | 92 | r_sin.* = trig.cosdf(x + sc3pio2); |
| 93 | r_cos.* = -trig.__sindf(x + sc3pio2); | 93 | r_cos.* = -trig.sindf(x + sc3pio2); |
| 94 | } else { | 94 | } else { |
| 95 | r_sin.* = -trig.__cosdf(x - sc3pio2); | 95 | r_sin.* = -trig.cosdf(x - sc3pio2); |
| 96 | r_cos.* = trig.__sindf(x - sc3pio2); | 96 | r_cos.* = trig.sindf(x - sc3pio2); |
| 97 | } | 97 | } |
| 98 | return; | 98 | return; |
| 99 | } | 99 | } |
| 100 | r_sin.* = trig.__sindf(if (sign) x + sc4pio2 else x - sc4pio2); | 100 | r_sin.* = trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2); |
| 101 | r_cos.* = trig.__cosdf(if (sign) x + sc4pio2 else x - sc4pio2); | 101 | r_cos.* = trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2); |
| 102 | return; | 102 | return; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| ... | @@ -113,8 +113,8 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | ... | @@ -113,8 +113,8 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 113 | // general argument reduction needed | 113 | // general argument reduction needed |
| 114 | var y: f64 = undefined; | 114 | var y: f64 = undefined; |
| 115 | const n = rem_pio2f(x, &y); | 115 | const n = rem_pio2f(x, &y); |
| 116 | const s = trig.__sindf(y); | 116 | const s = trig.sindf(y); |
| 117 | const c = trig.__cosdf(y); | 117 | const c = trig.cosdf(y); |
| 118 | switch (n & 3) { | 118 | switch (n & 3) { |
| 119 | 0 => { | 119 | 0 => { |
| 120 | r_sin.* = s; | 120 | r_sin.* = s; |
| ... | @@ -154,8 +154,8 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { | ... | @@ -154,8 +154,8 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { |
| 154 | r_cos.* = 1.0; | 154 | r_cos.* = 1.0; |
| 155 | return; | 155 | return; |
| 156 | } | 156 | } |
| 157 | r_sin.* = trig.__sin(x, 0.0, 0); | 157 | r_sin.* = trig.sin(x, 0.0, 0); |
| 158 | r_cos.* = trig.__cos(x, 0.0); | 158 | r_cos.* = trig.cos(x, 0.0); |
| 159 | return; | 159 | return; |
| 160 | } | 160 | } |
| 161 | 161 | ||
| ... | @@ -170,8 +170,8 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { | ... | @@ -170,8 +170,8 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { |
| 170 | // argument reduction needed | 170 | // argument reduction needed |
| 171 | var y: [2]f64 = undefined; | 171 | var y: [2]f64 = undefined; |
| 172 | const n = rem_pio2(x, &y); | 172 | const n = rem_pio2(x, &y); |
| 173 | const s = trig.__sin(y[0], y[1], 1); | 173 | const s = trig.sin(y[0], y[1], 1); |
| 174 | const c = trig.__cos(y[0], y[1]); | 174 | const c = trig.cos(y[0], y[1]); |
| 175 | switch (n & 3) { | 175 | switch (n & 3) { |
| 176 | 0 => { | 176 | 0 => { |
| 177 | r_sin.* = s; | 177 | r_sin.* = s; |
| ... | @@ -216,15 +216,15 @@ fn sincoslGeneric(comptime T: type, x: T, r_sin: *T, r_cos: *T) void { | ... | @@ -216,15 +216,15 @@ fn sincoslGeneric(comptime T: type, x: T, r_sin: *T, r_cos: *T) void { |
| 216 | r_cos.* = 1.0 + x; | 216 | r_cos.* = 1.0 + x; |
| 217 | return; | 217 | return; |
| 218 | } | 218 | } |
| 219 | r_sin.* = trig.__sinl(T, x, 0.0, 0); | 219 | r_sin.* = trig.sinl(T, x, 0.0, 0); |
| 220 | r_cos.* = trig.__cosl(T, x, 0.0); | 220 | r_cos.* = trig.cosl(T, x, 0.0); |
| 221 | return; | 221 | return; |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | var y: [2]T = undefined; | 224 | var y: [2]T = undefined; |
| 225 | const n = rem_pio2l(T, x, &y); | 225 | const n = rem_pio2l(T, x, &y); |
| 226 | const s = trig.__sinl(T, y[0], y[1], 1); | 226 | const s = trig.sinl(T, y[0], y[1], 1); |
| 227 | const c = trig.__cosl(T, y[0], y[1]); | 227 | const c = trig.cosl(T, y[0], y[1]); |
| 228 | switch (n & 3) { | 228 | switch (n & 3) { |
| 229 | 0 => { | 229 | 0 => { |
| 230 | r_sin.* = s; | 230 | r_sin.* = s; |
| ... | @@ -245,7 +245,7 @@ fn sincoslGeneric(comptime T: type, x: T, r_sin: *T, r_cos: *T) void { | ... | @@ -245,7 +245,7 @@ fn sincoslGeneric(comptime T: type, x: T, r_sin: *T, r_cos: *T) void { |
| 245 | } | 245 | } |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | pub fn __sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { | 248 | pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { |
| 249 | return sincoslGeneric(f80, x, r_sin, r_cos); | 249 | return sincoslGeneric(f80, x, r_sin, r_cos); |
| 250 | } | 250 | } |
| 251 | 251 | ||
| ... | @@ -255,10 +255,10 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { | ... | @@ -255,10 +255,10 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { |
| 255 | 255 | ||
| 256 | pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void { | 256 | pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void { |
| 257 | switch (@typeInfo(c_longdouble).float.bits) { | 257 | switch (@typeInfo(c_longdouble).float.bits) { |
| 258 | 16 => return __sincosh(x, r_sin, r_cos), | 258 | 16 => return sincosh(x, r_sin, r_cos), |
| 259 | 32 => return sincosf(x, r_sin, r_cos), | 259 | 32 => return sincosf(x, r_sin, r_cos), |
| 260 | 64 => return sincos(x, r_sin, r_cos), | 260 | 64 => return sincos(x, r_sin, r_cos), |
| 261 | 80 => return __sincosx(x, r_sin, r_cos), | 261 | 80 => return sincosx(x, r_sin, r_cos), |
| 262 | 128 => return sincosq(x, r_sin, r_cos), | 262 | 128 => return sincosq(x, r_sin, r_cos), |
| 263 | else => @compileError("unreachable"), | 263 | else => @compileError("unreachable"), |
| 264 | } | 264 | } |
| ... | @@ -268,7 +268,7 @@ fn testSincosSpecial(comptime T: type) !void { | ... | @@ -268,7 +268,7 @@ fn testSincosSpecial(comptime T: type) !void { |
| 268 | const f = switch (T) { | 268 | const f = switch (T) { |
| 269 | f32 => sincosf, | 269 | f32 => sincosf, |
| 270 | f64 => sincos, | 270 | f64 => sincos, |
| 271 | f80 => __sincosx, | 271 | f80 => sincosx, |
| 272 | f128 => sincosq, | 272 | f128 => sincosq, |
| 273 | else => @compileError("unimplemented"), | 273 | else => @compileError("unimplemented"), |
| 274 | }; | 274 | }; |
| ... | @@ -378,31 +378,31 @@ test "sincos80.normal" { | ... | @@ -378,31 +378,31 @@ test "sincos80.normal" { |
| 378 | var s: f80 = undefined; | 378 | var s: f80 = undefined; |
| 379 | var c: f80 = undefined; | 379 | var c: f80 = undefined; |
| 380 | 380 | ||
| 381 | __sincosx(0.0, &s, &c); | 381 | sincosx(0.0, &s, &c); |
| 382 | try expectApproxEqAbs(@as(f80, 0.0), s, epsilon); | 382 | try expectApproxEqAbs(@as(f80, 0.0), s, epsilon); |
| 383 | try expectApproxEqAbs(@as(f80, 1.0), c, epsilon); | 383 | try expectApproxEqAbs(@as(f80, 1.0), c, epsilon); |
| 384 | 384 | ||
| 385 | __sincosx(0.2, &s, &c); | 385 | sincosx(0.2, &s, &c); |
| 386 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon); | 386 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon); |
| 387 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon); | 387 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon); |
| 388 | 388 | ||
| 389 | __sincosx(0.8923, &s, &c); | 389 | sincosx(0.8923, &s, &c); |
| 390 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon); | 390 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon); |
| 391 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon); | 391 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon); |
| 392 | 392 | ||
| 393 | __sincosx(1.5, &s, &c); | 393 | sincosx(1.5, &s, &c); |
| 394 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon); | 394 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon); |
| 395 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); | 395 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); |
| 396 | 396 | ||
| 397 | __sincosx(-1.5, &s, &c); | 397 | sincosx(-1.5, &s, &c); |
| 398 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon); | 398 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon); |
| 399 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); | 399 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); |
| 400 | 400 | ||
| 401 | __sincosx(37.45, &s, &c); | 401 | sincosx(37.45, &s, &c); |
| 402 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon); | 402 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon); |
| 403 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon); | 403 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon); |
| 404 | 404 | ||
| 405 | __sincosx(89.123, &s, &c); | 405 | sincosx(89.123, &s, &c); |
| 406 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon); | 406 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon); |
| 407 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon); | 407 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon); |
| 408 | } | 408 | } |
lib/compiler_rt/tan.zig+23-23| ... | @@ -24,10 +24,10 @@ const compiler_rt = @import("../compiler_rt.zig"); | ... | @@ -24,10 +24,10 @@ const compiler_rt = @import("../compiler_rt.zig"); |
| 24 | const symbol = @import("../compiler_rt.zig").symbol; | 24 | const symbol = @import("../compiler_rt.zig").symbol; |
| 25 | 25 | ||
| 26 | comptime { | 26 | comptime { |
| 27 | symbol(&__tanh, "__tanh"); | 27 | symbol(&tanh, "__tanh"); |
| 28 | symbol(&tanf, "tanf"); | 28 | symbol(&tanf, "tanf"); |
| 29 | symbol(&tan, "tan"); | 29 | symbol(&tan, "tan"); |
| 30 | symbol(&__tanx, "__tanx"); | 30 | symbol(&tanx, "__tanx"); |
| 31 | if (compiler_rt.want_ppc_abi) { | 31 | if (compiler_rt.want_ppc_abi) { |
| 32 | symbol(&tanq, "tanf128"); | 32 | symbol(&tanq, "tanf128"); |
| 33 | } | 33 | } |
| ... | @@ -35,7 +35,7 @@ comptime { | ... | @@ -35,7 +35,7 @@ comptime { |
| 35 | symbol(&tanl, "tanl"); | 35 | symbol(&tanl, "tanl"); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | pub fn __tanh(x: f16) callconv(.c) f16 { | 38 | pub fn tanh(x: f16) callconv(.c) f16 { |
| 39 | // TODO: more efficient implementation | 39 | // TODO: more efficient implementation |
| 40 | return @floatCast(tanf(x)); | 40 | return @floatCast(tanf(x)); |
| 41 | } | 41 | } |
| ... | @@ -63,20 +63,20 @@ pub fn tanf(x: f32) callconv(.c) f32 { | ... | @@ -63,20 +63,20 @@ pub fn tanf(x: f32) callconv(.c) f32 { |
| 63 | } | 63 | } |
| 64 | return x; | 64 | return x; |
| 65 | } | 65 | } |
| 66 | return kernel.__tandf(x, false); | 66 | return kernel.tandf(x, false); |
| 67 | } | 67 | } |
| 68 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 | 68 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 |
| 69 | if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4 | 69 | if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4 |
| 70 | return kernel.__tandf((if (sign) x + t1pio2 else x - t1pio2), true); | 70 | return kernel.tandf((if (sign) x + t1pio2 else x - t1pio2), true); |
| 71 | } else { | 71 | } else { |
| 72 | return kernel.__tandf((if (sign) x + t2pio2 else x - t2pio2), false); | 72 | return kernel.tandf((if (sign) x + t2pio2 else x - t2pio2), false); |
| 73 | } | 73 | } |
| 74 | } | 74 | } |
| 75 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 | 75 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 |
| 76 | if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4 | 76 | if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4 |
| 77 | return kernel.__tandf((if (sign) x + t3pio2 else x - t3pio2), true); | 77 | return kernel.tandf((if (sign) x + t3pio2 else x - t3pio2), true); |
| 78 | } else { | 78 | } else { |
| 79 | return kernel.__tandf((if (sign) x + t4pio2 else x - t4pio2), false); | 79 | return kernel.tandf((if (sign) x + t4pio2 else x - t4pio2), false); |
| 80 | } | 80 | } |
| 81 | } | 81 | } |
| 82 | 82 | ||
| ... | @@ -87,7 +87,7 @@ pub fn tanf(x: f32) callconv(.c) f32 { | ... | @@ -87,7 +87,7 @@ pub fn tanf(x: f32) callconv(.c) f32 { |
| 87 | 87 | ||
| 88 | var y: f64 = undefined; | 88 | var y: f64 = undefined; |
| 89 | const n = rem_pio2f(x, &y); | 89 | const n = rem_pio2f(x, &y); |
| 90 | return kernel.__tandf(y, n & 1 != 0); | 90 | return kernel.tandf(y, n & 1 != 0); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | pub fn tan(x: f64) callconv(.c) f64 { | 93 | pub fn tan(x: f64) callconv(.c) f64 { |
| ... | @@ -107,7 +107,7 @@ pub fn tan(x: f64) callconv(.c) f64 { | ... | @@ -107,7 +107,7 @@ pub fn tan(x: f64) callconv(.c) f64 { |
| 107 | } | 107 | } |
| 108 | return x; | 108 | return x; |
| 109 | } | 109 | } |
| 110 | return kernel.__tan(x, 0.0, false); | 110 | return kernel.tan(x, 0.0, false); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | // tan(Inf or NaN) is NaN | 113 | // tan(Inf or NaN) is NaN |
| ... | @@ -117,7 +117,7 @@ pub fn tan(x: f64) callconv(.c) f64 { | ... | @@ -117,7 +117,7 @@ pub fn tan(x: f64) callconv(.c) f64 { |
| 117 | 117 | ||
| 118 | var y: [2]f64 = undefined; | 118 | var y: [2]f64 = undefined; |
| 119 | const n = rem_pio2(x, &y); | 119 | const n = rem_pio2(x, &y); |
| 120 | return kernel.__tan(y[0], y[1], n & 1 != 0); | 120 | return kernel.tan(y[0], y[1], n & 1 != 0); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | fn tanlGeneric(comptime T: type, x: T) T { | 123 | fn tanlGeneric(comptime T: type, x: T) T { |
| ... | @@ -137,15 +137,15 @@ fn tanlGeneric(comptime T: type, x: T) T { | ... | @@ -137,15 +137,15 @@ fn tanlGeneric(comptime T: type, x: T) T { |
| 137 | } | 137 | } |
| 138 | return x; | 138 | return x; |
| 139 | } | 139 | } |
| 140 | return kernel.__tanl(T, x, 0.0, 0); | 140 | return kernel.tanl(T, x, 0.0, 0); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | var y: [2]T = undefined; | 143 | var y: [2]T = undefined; |
| 144 | const n = rem_pio2l(T, x, &y); | 144 | const n = rem_pio2l(T, x, &y); |
| 145 | return kernel.__tanl(T, y[0], y[1], n & 1); | 145 | return kernel.tanl(T, y[0], y[1], n & 1); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | pub fn __tanx(x: f80) callconv(.c) f80 { | 148 | pub fn tanx(x: f80) callconv(.c) f80 { |
| 149 | return tanlGeneric(f80, x); | 149 | return tanlGeneric(f80, x); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| ... | @@ -155,10 +155,10 @@ pub fn tanq(x: f128) callconv(.c) f128 { | ... | @@ -155,10 +155,10 @@ pub fn tanq(x: f128) callconv(.c) f128 { |
| 155 | 155 | ||
| 156 | pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble { | 156 | pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble { |
| 157 | switch (@typeInfo(c_longdouble).float.bits) { | 157 | switch (@typeInfo(c_longdouble).float.bits) { |
| 158 | 16 => return __tanh(x), | 158 | 16 => return tanh(x), |
| 159 | 32 => return tanf(x), | 159 | 32 => return tanf(x), |
| 160 | 64 => return tan(x), | 160 | 64 => return tan(x), |
| 161 | 80 => return __tanx(x), | 161 | 80 => return tanx(x), |
| 162 | 128 => return tanq(x), | 162 | 128 => return tanq(x), |
| 163 | else => @compileError("unreachable"), | 163 | else => @compileError("unreachable"), |
| 164 | } | 164 | } |
| ... | @@ -184,7 +184,7 @@ fn testTanSpecial(comptime T: type) !void { | ... | @@ -184,7 +184,7 @@ fn testTanSpecial(comptime T: type) !void { |
| 184 | const f = switch (T) { | 184 | const f = switch (T) { |
| 185 | f32 => tanf, | 185 | f32 => tanf, |
| 186 | f64 => tan, | 186 | f64 => tan, |
| 187 | f80 => __tanx, | 187 | f80 => tanx, |
| 188 | f128 => tanq, | 188 | f128 => tanq, |
| 189 | else => @compileError("unimplemented"), | 189 | else => @compileError("unimplemented"), |
| 190 | }; | 190 | }; |
| ... | @@ -207,12 +207,12 @@ test "tan64.normal" { | ... | @@ -207,12 +207,12 @@ test "tan64.normal" { |
| 207 | test "tan80.normal" { | 207 | test "tan80.normal" { |
| 208 | const epsilon = math.floatEps(f80); | 208 | const epsilon = math.floatEps(f80); |
| 209 | 209 | ||
| 210 | try expectApproxEqAbs(@as(f80, 0.0), __tanx(0.0), epsilon); | 210 | try expectApproxEqAbs(@as(f80, 0.0), tanx(0.0), epsilon); |
| 211 | try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), __tanx(0.2), epsilon); | 211 | try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tanx(0.2), epsilon); |
| 212 | try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), __tanx(0.8923), epsilon); | 212 | try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tanx(0.8923), epsilon); |
| 213 | try expectApproxEqAbs(@as(f80, 14.10141994717171938764), __tanx(1.5), epsilon); | 213 | try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tanx(1.5), epsilon); |
| 214 | try expectApproxEqAbs(@as(f80, -0.25439607116885656232), __tanx(37.45), epsilon); | 214 | try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tanx(37.45), epsilon); |
| 215 | try expectApproxEqAbs(@as(f80, 2.2858376251355320963), __tanx(89.123), epsilon); | 215 | try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tanx(89.123), epsilon); |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | test "tan128.normal" { | 218 | test "tan128.normal" { |
lib/compiler_rt/trig.zig+15-14| ... | @@ -11,8 +11,9 @@ | ... | @@ -11,8 +11,9 @@ |
| 11 | // https://git.musl-libc.org/cgit/musl/tree/src/math/__cosl.c | 11 | // https://git.musl-libc.org/cgit/musl/tree/src/math/__cosl.c |
| 12 | // https://git.musl-libc.org/cgit/musl/tree/src/math/__tanl.c | 12 | // https://git.musl-libc.org/cgit/musl/tree/src/math/__tanl.c |
| 13 | 13 | ||
| 14 | /// pi divided by 4 | 14 | const std = @import("std"); |
| 15 | pub const pi_4 = 0.78539816339744830962; | 15 | |
| 16 | pub const pi_4 = std.math.pi / 4.0; | ||
| 16 | 17 | ||
| 17 | /// kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 | 18 | /// kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 |
| 18 | /// Input x is assumed to be bounded by ~pi/4 in magnitude. | 19 | /// Input x is assumed to be bounded by ~pi/4 in magnitude. |
| ... | @@ -49,7 +50,7 @@ pub const pi_4 = 0.78539816339744830962; | ... | @@ -49,7 +50,7 @@ pub const pi_4 = 0.78539816339744830962; |
| 49 | /// expression for cos(). Retention happens in all cases tested | 50 | /// expression for cos(). Retention happens in all cases tested |
| 50 | /// under FreeBSD, so don't pessimize things by forcibly clipping | 51 | /// under FreeBSD, so don't pessimize things by forcibly clipping |
| 51 | /// any extra precision in w. | 52 | /// any extra precision in w. |
| 52 | pub fn __cos(x: f64, y: f64) f64 { | 53 | pub fn cos(x: f64, y: f64) f64 { |
| 53 | const C1 = 4.16666666666666019037e-02; // 0x3FA55555, 0x5555554C | 54 | const C1 = 4.16666666666666019037e-02; // 0x3FA55555, 0x5555554C |
| 54 | const C2 = -1.38888888888741095749e-03; // 0xBF56C16C, 0x16C15177 | 55 | const C2 = -1.38888888888741095749e-03; // 0xBF56C16C, 0x16C15177 |
| 55 | const C3 = 2.48015872894767294178e-05; // 0x3EFA01A0, 0x19CB1590 | 56 | const C3 = 2.48015872894767294178e-05; // 0x3EFA01A0, 0x19CB1590 |
| ... | @@ -65,7 +66,7 @@ pub fn __cos(x: f64, y: f64) f64 { | ... | @@ -65,7 +66,7 @@ pub fn __cos(x: f64, y: f64) f64 { |
| 65 | return w + (((1.0 - w) - hz) + (z * r - x * y)); | 66 | return w + (((1.0 - w) - hz) + (z * r - x * y)); |
| 66 | } | 67 | } |
| 67 | 68 | ||
| 68 | pub fn __cosdf(x: f64) f32 { | 69 | pub fn cosdf(x: f64) f32 { |
| 69 | // |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). | 70 | // |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). |
| 70 | const C0 = -0x1ffffffd0c5e81.0p-54; // -0.499999997251031003120 | 71 | const C0 = -0x1ffffffd0c5e81.0p-54; // -0.499999997251031003120 |
| 71 | const C1 = 0x155553e1053a42.0p-57; // 0.0416666233237390631894 | 72 | const C1 = 0x155553e1053a42.0p-57; // 0.0416666233237390631894 |
| ... | @@ -79,7 +80,7 @@ pub fn __cosdf(x: f64) f32 { | ... | @@ -79,7 +80,7 @@ pub fn __cosdf(x: f64) f32 { |
| 79 | return @floatCast(((1.0 + z * C0) + w * C1) + (w * z) * r); | 80 | return @floatCast(((1.0 + z * C0) + w * C1) + (w * z) * r); |
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | pub fn __cosl(comptime T: type, x: T, y: T) T { | 83 | pub fn cosl(comptime T: type, x: T, y: T) T { |
| 83 | const impl = switch (T) { | 84 | const impl = switch (T) { |
| 84 | f80 => struct { | 85 | f80 => struct { |
| 85 | const C1: T = 0.0416666666666666666136; | 86 | const C1: T = 0.0416666666666666666136; |
| ... | @@ -115,7 +116,7 @@ pub fn __cosl(comptime T: type, x: T, y: T) T { | ... | @@ -115,7 +116,7 @@ pub fn __cosl(comptime T: type, x: T, y: T) T { |
| 115 | z * (C7 + z * (C8 + z * (C9 + z * (C10 + z * C11)))))))))); | 116 | z * (C7 + z * (C8 + z * (C9 + z * (C10 + z * C11)))))))))); |
| 116 | } | 117 | } |
| 117 | }, | 118 | }, |
| 118 | else => @compileError("__cosl supports only f80 and f128, got: " ++ @typeName(T)), | 119 | else => @compileError("cosl supports only f80 and f128, got: " ++ @typeName(T)), |
| 119 | }; | 120 | }; |
| 120 | 121 | ||
| 121 | const z = x * x; | 122 | const z = x * x; |
| ... | @@ -152,7 +153,7 @@ pub fn __cosl(comptime T: type, x: T, y: T) T { | ... | @@ -152,7 +153,7 @@ pub fn __cosl(comptime T: type, x: T, y: T) T { |
| 152 | /// r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) | 153 | /// r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) |
| 153 | /// then 3 2 | 154 | /// then 3 2 |
| 154 | /// sin(x) = x + (S1*x + (x *(r-y/2)+y)) | 155 | /// sin(x) = x + (S1*x + (x *(r-y/2)+y)) |
| 155 | pub fn __sin(x: f64, y: f64, iy: i32) f64 { | 156 | pub fn sin(x: f64, y: f64, iy: i32) f64 { |
| 156 | const S1 = -1.66666666666666324348e-01; // 0xBFC55555, 0x55555549 | 157 | const S1 = -1.66666666666666324348e-01; // 0xBFC55555, 0x55555549 |
| 157 | const S2 = 8.33333333332248946124e-03; // 0x3F811111, 0x1110F8A6 | 158 | const S2 = 8.33333333332248946124e-03; // 0x3F811111, 0x1110F8A6 |
| 158 | const S3 = -1.98412698298579493134e-04; // 0xBF2A01A0, 0x19C161D5 | 159 | const S3 = -1.98412698298579493134e-04; // 0xBF2A01A0, 0x19C161D5 |
| ... | @@ -171,7 +172,7 @@ pub fn __sin(x: f64, y: f64, iy: i32) f64 { | ... | @@ -171,7 +172,7 @@ pub fn __sin(x: f64, y: f64, iy: i32) f64 { |
| 171 | } | 172 | } |
| 172 | } | 173 | } |
| 173 | 174 | ||
| 174 | pub fn __sinl(comptime T: type, x: T, y: T, iy: i32) T { | 175 | pub fn sinl(comptime T: type, x: T, y: T, iy: i32) T { |
| 175 | const impl = switch (T) { | 176 | const impl = switch (T) { |
| 176 | f80 => struct { | 177 | f80 => struct { |
| 177 | const S1: T = -0.166666666666666666671; | 178 | const S1: T = -0.166666666666666666671; |
| ... | @@ -209,7 +210,7 @@ pub fn __sinl(comptime T: type, x: T, y: T, iy: i32) T { | ... | @@ -209,7 +210,7 @@ pub fn __sinl(comptime T: type, x: T, y: T, iy: i32) T { |
| 209 | z * (S9 + z * (S10 + z * (S11 + z * S12))))))))); | 210 | z * (S9 + z * (S10 + z * (S11 + z * S12))))))))); |
| 210 | } | 211 | } |
| 211 | }, | 212 | }, |
| 212 | else => @compileError("__sinl supports only f80 and f128, got: " ++ @typeName(T)), | 213 | else => @compileError("sinl supports only f80 and f128, got: " ++ @typeName(T)), |
| 213 | }; | 214 | }; |
| 214 | 215 | ||
| 215 | const z = x * x; | 216 | const z = x * x; |
| ... | @@ -223,7 +224,7 @@ pub fn __sinl(comptime T: type, x: T, y: T, iy: i32) T { | ... | @@ -223,7 +224,7 @@ pub fn __sinl(comptime T: type, x: T, y: T, iy: i32) T { |
| 223 | return x - ((z * (0.5 * y - v * r) - y) - v * impl.S1); | 224 | return x - ((z * (0.5 * y - v * r) - y) - v * impl.S1); |
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | pub fn __sindf(x: f64) f32 { | 227 | pub fn sindf(x: f64) f32 { |
| 227 | // |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). | 228 | // |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). |
| 228 | const S1 = -0x15555554cbac77.0p-55; // -0.166666666416265235595 | 229 | const S1 = -0x15555554cbac77.0p-55; // -0.166666666416265235595 |
| 229 | const S2 = 0x111110896efbb2.0p-59; // 0.0083333293858894631756 | 230 | const S2 = 0x111110896efbb2.0p-59; // 0.0083333293858894631756 |
| ... | @@ -270,7 +271,7 @@ pub fn __sindf(x: f64) f32 { | ... | @@ -270,7 +271,7 @@ pub fn __sindf(x: f64) f32 { |
| 270 | /// 4. For x in [0.67434,pi/4], let y = pi/4 - x, then | 271 | /// 4. For x in [0.67434,pi/4], let y = pi/4 - x, then |
| 271 | /// tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) | 272 | /// tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) |
| 272 | /// = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) | 273 | /// = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) |
| 273 | pub fn __tan(x_: f64, y_: f64, odd: bool) f64 { | 274 | pub fn tan(x_: f64, y_: f64, odd: bool) f64 { |
| 274 | var x = x_; | 275 | var x = x_; |
| 275 | var y = y_; | 276 | var y = y_; |
| 276 | 277 | ||
| ... | @@ -343,7 +344,7 @@ pub fn __tan(x_: f64, y_: f64, odd: bool) f64 { | ... | @@ -343,7 +344,7 @@ pub fn __tan(x_: f64, y_: f64, odd: bool) f64 { |
| 343 | return a0 + a * (1.0 + a0 * w0 + a0 * v); | 344 | return a0 + a * (1.0 + a0 * w0 + a0 * v); |
| 344 | } | 345 | } |
| 345 | 346 | ||
| 346 | pub fn __tandf(x: f64, odd: bool) f32 { | 347 | pub fn tandf(x: f64, odd: bool) f32 { |
| 347 | // |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). | 348 | // |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). |
| 348 | const T = [_]f64{ | 349 | const T = [_]f64{ |
| 349 | 0x15554d3418c99f.0p-54, // 0.333331395030791399758 | 350 | 0x15554d3418c99f.0p-54, // 0.333331395030791399758 |
| ... | @@ -376,7 +377,7 @@ pub fn __tandf(x: f64, odd: bool) f32 { | ... | @@ -376,7 +377,7 @@ pub fn __tandf(x: f64, odd: bool) f32 { |
| 376 | return @floatCast(if (odd) -1.0 / r0 else r0); | 377 | return @floatCast(if (odd) -1.0 / r0 else r0); |
| 377 | } | 378 | } |
| 378 | 379 | ||
| 379 | pub fn __tanl(comptime T: type, x_: T, y_: T, odd: i32) T { | 380 | pub fn tanl(comptime T: type, x_: T, y_: T, odd: i32) T { |
| 380 | var x = x_; | 381 | var x = x_; |
| 381 | var y = y_; | 382 | var y = y_; |
| 382 | const impl = switch (T) { | 383 | const impl = switch (T) { |
| ... | @@ -456,7 +457,7 @@ pub fn __tanl(comptime T: type, x_: T, y_: T, odd: i32) T { | ... | @@ -456,7 +457,7 @@ pub fn __tanl(comptime T: type, x_: T, y_: T, odd: i32) T { |
| 456 | w * (T47 + w * (T51 + w * T55))))))))))); | 457 | w * (T47 + w * (T51 + w * T55))))))))))); |
| 457 | } | 458 | } |
| 458 | }, | 459 | }, |
| 459 | else => @compileError("__tanl supports only f80 and f128, got: " ++ @typeName(T)), | 460 | else => @compileError("tanl supports only f80 and f128, got: " ++ @typeName(T)), |
| 460 | }; | 461 | }; |
| 461 | 462 | ||
| 462 | const big = @abs(x) >= 0.67434; | 463 | const big = @abs(x) >= 0.67434; |