| author | |
| committer | |
| log | f7f03c699d2dee4c3eec2108e159bbe300e24c6f |
| tree | a8fda028d8aae82b9fd2fd8488b6e6e11643402e |
| parent | 0b2ed45f5fd69cb5f3afb3118726b17859bda0f5 |
3 files changed, 264 insertions(+), 49 deletions(-)
lib/std/special/compiler_rt/cos.zig+17-17| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | const kernel = @import("trig.zig"); | 5 | const trig = @import("trig.zig"); |
| 6 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; | 6 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; |
| 7 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; | 7 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; |
| 8 | 8 | ||
| ... | @@ -28,27 +28,27 @@ pub fn cosf(x: f32) callconv(.C) f32 { | ... | @@ -28,27 +28,27 @@ pub fn cosf(x: f32) callconv(.C) f32 { |
| 28 | math.doNotOptimizeAway(x + 0x1p120); | 28 | math.doNotOptimizeAway(x + 0x1p120); |
| 29 | return 1.0; | 29 | return 1.0; |
| 30 | } | 30 | } |
| 31 | return kernel.__cosdf(x); | 31 | return trig.__cosdf(x); |
| 32 | } | 32 | } |
| 33 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 | 33 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 |
| 34 | if (ix > 0x4016cbe3) { // |x| ~> 3*pi/4 | 34 | if (ix > 0x4016cbe3) { // |x| ~> 3*pi/4 |
| 35 | return -kernel.__cosdf(if (sign) x + c2pio2 else x - c2pio2); | 35 | return -trig.__cosdf(if (sign) x + c2pio2 else x - c2pio2); |
| 36 | } else { | 36 | } else { |
| 37 | if (sign) { | 37 | if (sign) { |
| 38 | return kernel.__sindf(x + c1pio2); | 38 | return trig.__sindf(x + c1pio2); |
| 39 | } else { | 39 | } else { |
| 40 | return kernel.__sindf(c1pio2 - x); | 40 | return trig.__sindf(c1pio2 - x); |
| 41 | } | 41 | } |
| 42 | } | 42 | } |
| 43 | } | 43 | } |
| 44 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 | 44 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 |
| 45 | if (ix > 0x40afeddf) { // |x| ~> 7*pi/4 | 45 | if (ix > 0x40afeddf) { // |x| ~> 7*pi/4 |
| 46 | return kernel.__cosdf(if (sign) x + c4pio2 else x - c4pio2); | 46 | return trig.__cosdf(if (sign) x + c4pio2 else x - c4pio2); |
| 47 | } else { | 47 | } else { |
| 48 | if (sign) { | 48 | if (sign) { |
| 49 | return kernel.__sindf(-x - c3pio2); | 49 | return trig.__sindf(-x - c3pio2); |
| 50 | } else { | 50 | } else { |
| 51 | return kernel.__sindf(x - c3pio2); | 51 | return trig.__sindf(x - c3pio2); |
| 52 | } | 52 | } |
| 53 | } | 53 | } |
| 54 | } | 54 | } |
| ... | @@ -61,10 +61,10 @@ pub fn cosf(x: f32) callconv(.C) f32 { | ... | @@ -61,10 +61,10 @@ pub fn cosf(x: f32) callconv(.C) f32 { |
| 61 | var y: f64 = undefined; | 61 | var y: f64 = undefined; |
| 62 | const n = rem_pio2f(x, &y); | 62 | const n = rem_pio2f(x, &y); |
| 63 | return switch (n & 3) { | 63 | return switch (n & 3) { |
| 64 | 0 => kernel.__cosdf(y), | 64 | 0 => trig.__cosdf(y), |
| 65 | 1 => kernel.__sindf(-y), | 65 | 1 => trig.__sindf(-y), |
| 66 | 2 => -kernel.__cosdf(y), | 66 | 2 => -trig.__cosdf(y), |
| 67 | else => kernel.__sindf(y), | 67 | else => trig.__sindf(y), |
| 68 | }; | 68 | }; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| ... | @@ -79,7 +79,7 @@ pub fn cos(x: f64) callconv(.C) f64 { | ... | @@ -79,7 +79,7 @@ pub fn cos(x: f64) callconv(.C) f64 { |
| 79 | math.doNotOptimizeAway(x + 0x1p120); | 79 | math.doNotOptimizeAway(x + 0x1p120); |
| 80 | return 1.0; | 80 | return 1.0; |
| 81 | } | 81 | } |
| 82 | return kernel.__cos(x, 0); | 82 | return trig.__cos(x, 0); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | // cos(Inf or NaN) is NaN | 85 | // cos(Inf or NaN) is NaN |
| ... | @@ -90,10 +90,10 @@ pub fn cos(x: f64) callconv(.C) f64 { | ... | @@ -90,10 +90,10 @@ pub fn cos(x: f64) callconv(.C) f64 { |
| 90 | var y: [2]f64 = undefined; | 90 | var y: [2]f64 = undefined; |
| 91 | const n = rem_pio2(x, &y); | 91 | const n = rem_pio2(x, &y); |
| 92 | return switch (n & 3) { | 92 | return switch (n & 3) { |
| 93 | 0 => kernel.__cos(y[0], y[1]), | 93 | 0 => trig.__cos(y[0], y[1]), |
| 94 | 1 => -kernel.__sin(y[0], y[1], 1), | 94 | 1 => -trig.__sin(y[0], y[1], 1), |
| 95 | 2 => -kernel.__cos(y[0], y[1]), | 95 | 2 => -trig.__cos(y[0], y[1]), |
| 96 | else => kernel.__sin(y[0], y[1], 1), | 96 | else => trig.__sin(y[0], y[1], 1), |
| 97 | }; | 97 | }; |
| 98 | } | 98 | } |
| 99 | 99 |
lib/std/special/compiler_rt/sin.zig+17-17| ... | @@ -8,7 +8,7 @@ const std = @import("std"); | ... | @@ -8,7 +8,7 @@ const std = @import("std"); |
| 8 | const math = std.math; | 8 | const math = std.math; |
| 9 | const expect = std.testing.expect; | 9 | const expect = std.testing.expect; |
| 10 | 10 | ||
| 11 | const kernel = @import("trig.zig"); | 11 | const trig = @import("trig.zig"); |
| 12 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; | 12 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; |
| 13 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; | 13 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; |
| 14 | 14 | ||
| ... | @@ -34,27 +34,27 @@ pub fn sinf(x: f32) callconv(.C) f32 { | ... | @@ -34,27 +34,27 @@ pub fn sinf(x: f32) callconv(.C) f32 { |
| 34 | math.doNotOptimizeAway(if (ix < 0x00800000) x / 0x1p120 else x + 0x1p120); | 34 | math.doNotOptimizeAway(if (ix < 0x00800000) x / 0x1p120 else x + 0x1p120); |
| 35 | return x; | 35 | return x; |
| 36 | } | 36 | } |
| 37 | return kernel.__sindf(x); | 37 | return trig.__sindf(x); |
| 38 | } | 38 | } |
| 39 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 | 39 | if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4 |
| 40 | if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4 | 40 | if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4 |
| 41 | if (sign) { | 41 | if (sign) { |
| 42 | return -kernel.__cosdf(x + s1pio2); | 42 | return -trig.__cosdf(x + s1pio2); |
| 43 | } else { | 43 | } else { |
| 44 | return kernel.__cosdf(x - s1pio2); | 44 | return trig.__cosdf(x - s1pio2); |
| 45 | } | 45 | } |
| 46 | } | 46 | } |
| 47 | return kernel.__sindf(if (sign) -(x + s2pio2) else -(x - s2pio2)); | 47 | return trig.__sindf(if (sign) -(x + s2pio2) else -(x - s2pio2)); |
| 48 | } | 48 | } |
| 49 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 | 49 | if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4 |
| 50 | if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4 | 50 | if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4 |
| 51 | if (sign) { | 51 | if (sign) { |
| 52 | return kernel.__cosdf(x + s3pio2); | 52 | return trig.__cosdf(x + s3pio2); |
| 53 | } else { | 53 | } else { |
| 54 | return -kernel.__cosdf(x - s3pio2); | 54 | return -trig.__cosdf(x - s3pio2); |
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | return kernel.__sindf(if (sign) x + s4pio2 else x - s4pio2); | 57 | return trig.__sindf(if (sign) x + s4pio2 else x - s4pio2); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | // sin(Inf or NaN) is NaN | 60 | // sin(Inf or NaN) is NaN |
| ... | @@ -65,10 +65,10 @@ pub fn sinf(x: f32) callconv(.C) f32 { | ... | @@ -65,10 +65,10 @@ pub fn sinf(x: f32) callconv(.C) f32 { |
| 65 | var y: f64 = undefined; | 65 | var y: f64 = undefined; |
| 66 | const n = rem_pio2f(x, &y); | 66 | const n = rem_pio2f(x, &y); |
| 67 | return switch (n & 3) { | 67 | return switch (n & 3) { |
| 68 | 0 => kernel.__sindf(y), | 68 | 0 => trig.__sindf(y), |
| 69 | 1 => kernel.__cosdf(y), | 69 | 1 => trig.__cosdf(y), |
| 70 | 2 => kernel.__sindf(-y), | 70 | 2 => trig.__sindf(-y), |
| 71 | else => -kernel.__cosdf(y), | 71 | else => -trig.__cosdf(y), |
| 72 | }; | 72 | }; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| ... | @@ -83,7 +83,7 @@ pub fn sin(x: f64) callconv(.C) f64 { | ... | @@ -83,7 +83,7 @@ pub fn sin(x: f64) callconv(.C) f64 { |
| 83 | math.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120); | 83 | math.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120); |
| 84 | return x; | 84 | return x; |
| 85 | } | 85 | } |
| 86 | return kernel.__sin(x, 0.0, 0); | 86 | return trig.__sin(x, 0.0, 0); |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | // sin(Inf or NaN) is NaN | 89 | // sin(Inf or NaN) is NaN |
| ... | @@ -94,10 +94,10 @@ pub fn sin(x: f64) callconv(.C) f64 { | ... | @@ -94,10 +94,10 @@ pub fn sin(x: f64) callconv(.C) f64 { |
| 94 | var y: [2]f64 = undefined; | 94 | var y: [2]f64 = undefined; |
| 95 | const n = rem_pio2(x, &y); | 95 | const n = rem_pio2(x, &y); |
| 96 | return switch (n & 3) { | 96 | return switch (n & 3) { |
| 97 | 0 => kernel.__sin(y[0], y[1], 1), | 97 | 0 => trig.__sin(y[0], y[1], 1), |
| 98 | 1 => kernel.__cos(y[0], y[1]), | 98 | 1 => trig.__cos(y[0], y[1]), |
| 99 | 2 => -kernel.__sin(y[0], y[1], 1), | 99 | 2 => -trig.__sin(y[0], y[1], 1), |
| 100 | else => -kernel.__cos(y[0], y[1]), | 100 | else => -trig.__cos(y[0], y[1]), |
| 101 | }; | 101 | }; |
| 102 | } | 102 | } |
| 103 | 103 |
lib/std/special/compiler_rt/sincos.zig+230-15| ... | @@ -1,27 +1,242 @@ | ... | @@ -1,27 +1,242 @@ |
| 1 | const std = @import("std"); | ||
| 2 | const math = std.math; | ||
| 1 | const sin = @import("sin.zig"); | 3 | const sin = @import("sin.zig"); |
| 2 | const cos = @import("cos.zig"); | 4 | const cos = @import("cos.zig"); |
| 5 | const trig = @import("trig.zig"); | ||
| 6 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; | ||
| 7 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; | ||
| 3 | 8 | ||
| 4 | pub fn __sincosh(a: f16, r_sin: *f16, r_cos: *f16) callconv(.C) void { | 9 | pub fn __sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.C) void { |
| 5 | r_sin.* = sin.__sinh(a); | 10 | // TODO: more efficient implementation |
| 6 | r_cos.* = cos.__cosh(a); | 11 | var big_sin: f32 = undefined; |
| 12 | var big_cos: f32 = undefined; | ||
| 13 | sincosf(x, &big_sin, &big_cos); | ||
| 14 | r_sin.* = @floatCast(f16, big_sin); | ||
| 15 | r_cos.* = @floatCast(f16, big_cos); | ||
| 7 | } | 16 | } |
| 8 | 17 | ||
| 9 | pub fn sincosf(a: f32, r_sin: *f32, r_cos: *f32) callconv(.C) void { | 18 | pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.C) void { |
| 10 | r_sin.* = sin.sinf(a); | 19 | const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 11 | r_cos.* = cos.cosf(a); | 20 | const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| 21 | const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 | ||
| 22 | const sc4pio2: f64 = 4.0 * math.pi / 2.0; // 0x401921FB, 0x54442D18 | ||
| 23 | |||
| 24 | const pre_ix = @bitCast(u32, x); | ||
| 25 | const sign = pre_ix >> 31 != 0; | ||
| 26 | const ix = pre_ix & 0x7fffffff; | ||
| 27 | |||
| 28 | // |x| ~<= pi/4 | ||
| 29 | if (ix <= 0x3f490fda) { | ||
| 30 | // |x| < 2**-12 | ||
| 31 | if (ix < 0x39800000) { | ||
| 32 | // raise inexact if x!=0 and underflow if subnormal | ||
| 33 | math.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120); | ||
| 34 | r_sin.* = x; | ||
| 35 | r_cos.* = 1.0; | ||
| 36 | return; | ||
| 37 | } | ||
| 38 | r_sin.* = trig.__sindf(x); | ||
| 39 | r_cos.* = trig.__cosdf(x); | ||
| 40 | return; | ||
| 41 | } | ||
| 42 | |||
| 43 | // |x| ~<= 5*pi/4 | ||
| 44 | if (ix <= 0x407b53d1) { | ||
| 45 | // |x| ~<= 3pi/4 | ||
| 46 | if (ix <= 0x4016cbe3) { | ||
| 47 | if (sign) { | ||
| 48 | r_sin.* = -trig.__cosdf(x + sc1pio2); | ||
| 49 | r_cos.* = trig.__sindf(x + sc1pio2); | ||
| 50 | } else { | ||
| 51 | r_sin.* = trig.__cosdf(sc1pio2 - x); | ||
| 52 | r_cos.* = trig.__sindf(sc1pio2 - x); | ||
| 53 | } | ||
| 54 | return; | ||
| 55 | } | ||
| 56 | // -sin(x+c) is not correct if x+c could be 0: -0 vs +0 | ||
| 57 | r_sin.* = -trig.__sindf(if (sign) x + sc2pio2 else x - sc2pio2); | ||
| 58 | r_cos.* = -trig.__cosdf(if (sign) x + sc2pio2 else x - sc2pio2); | ||
| 59 | return; | ||
| 60 | } | ||
| 61 | |||
| 62 | // |x| ~<= 9*pi/4 | ||
| 63 | if (ix <= 0x40e231d5) { | ||
| 64 | // |x| ~<= 7*pi/4 | ||
| 65 | if (ix <= 0x40afeddf) { | ||
| 66 | if (sign) { | ||
| 67 | r_sin.* = trig.__cosdf(x + sc3pio2); | ||
| 68 | r_cos.* = -trig.__sindf(x + sc3pio2); | ||
| 69 | } else { | ||
| 70 | r_sin.* = -trig.__cosdf(x - sc3pio2); | ||
| 71 | r_cos.* = trig.__sindf(x - sc3pio2); | ||
| 72 | } | ||
| 73 | return; | ||
| 74 | } | ||
| 75 | r_sin.* = trig.__sindf(if (sign) x + sc4pio2 else x - sc4pio2); | ||
| 76 | r_cos.* = trig.__cosdf(if (sign) x + sc4pio2 else x - sc4pio2); | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | |||
| 80 | // sin(Inf or NaN) is NaN | ||
| 81 | if (ix >= 0x7f800000) { | ||
| 82 | const result = x - x; | ||
| 83 | r_sin.* = result; | ||
| 84 | r_cos.* = result; | ||
| 85 | return; | ||
| 86 | } | ||
| 87 | |||
| 88 | // general argument reduction needed | ||
| 89 | var y: f64 = undefined; | ||
| 90 | const n = rem_pio2f(x, &y); | ||
| 91 | const s = trig.__sindf(y); | ||
| 92 | const c = trig.__cosdf(y); | ||
| 93 | switch (n & 3) { | ||
| 94 | 0 => { | ||
| 95 | r_sin.* = s; | ||
| 96 | r_cos.* = c; | ||
| 97 | }, | ||
| 98 | 1 => { | ||
| 99 | r_sin.* = c; | ||
| 100 | r_cos.* = -s; | ||
| 101 | }, | ||
| 102 | 2 => { | ||
| 103 | r_sin.* = -s; | ||
| 104 | r_cos.* = -c; | ||
| 105 | }, | ||
| 106 | else => { | ||
| 107 | r_sin.* = -c; | ||
| 108 | r_cos.* = s; | ||
| 109 | }, | ||
| 110 | } | ||
| 12 | } | 111 | } |
| 13 | 112 | ||
| 14 | pub fn sincos(a: f64, r_sin: *f64, r_cos: *f64) callconv(.C) void { | 113 | pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.C) void { |
| 15 | r_sin.* = sin.sin(a); | 114 | const ix = @truncate(u32, @bitCast(u64, x) >> 32) & 0x7fffffff; |
| 16 | r_cos.* = cos.cos(a); | 115 | |
| 116 | // |x| ~< pi/4 | ||
| 117 | if (ix <= 0x3fe921fb) { | ||
| 118 | // if |x| < 2**-27 * sqrt(2) | ||
| 119 | if (ix < 0x3e46a09e) { | ||
| 120 | // raise inexact if x != 0 and underflow if subnormal | ||
| 121 | math.doNotOptimizeAway(if (ix < 0x00100000) x / 0x1p120 else x + 0x1p120); | ||
| 122 | r_sin.* = x; | ||
| 123 | r_cos.* = 1.0; | ||
| 124 | return; | ||
| 125 | } | ||
| 126 | r_sin.* = trig.__sin(x, 0.0, 0); | ||
| 127 | r_cos.* = trig.__cos(x, 0.0); | ||
| 128 | return; | ||
| 129 | } | ||
| 130 | |||
| 131 | // sincos(Inf or NaN) is NaN | ||
| 132 | if (ix >= 0x7ff00000) { | ||
| 133 | const result = x - x; | ||
| 134 | r_sin.* = result; | ||
| 135 | r_cos.* = result; | ||
| 136 | return; | ||
| 137 | } | ||
| 138 | |||
| 139 | // argument reduction needed | ||
| 140 | var y: [2]f64 = undefined; | ||
| 141 | const n = rem_pio2(x, &y); | ||
| 142 | const s = trig.__sin(y[0], y[1], 1); | ||
| 143 | const c = trig.__cos(y[0], y[1]); | ||
| 144 | switch (n & 3) { | ||
| 145 | 0 => { | ||
| 146 | r_sin.* = s; | ||
| 147 | r_cos.* = c; | ||
| 148 | }, | ||
| 149 | 1 => { | ||
| 150 | r_sin.* = c; | ||
| 151 | r_cos.* = -s; | ||
| 152 | }, | ||
| 153 | 2 => { | ||
| 154 | r_sin.* = -s; | ||
| 155 | r_cos.* = -c; | ||
| 156 | }, | ||
| 157 | else => { | ||
| 158 | r_sin.* = -c; | ||
| 159 | r_cos.* = s; | ||
| 160 | }, | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | pub fn __sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.C) void { | ||
| 165 | // TODO: more efficient implementation | ||
| 166 | //return sincos_generic(f80, x, r_sin, r_cos); | ||
| 167 | var big_sin: f128 = undefined; | ||
| 168 | var big_cos: f128 = undefined; | ||
| 169 | sincosq(x, &big_sin, &big_cos); | ||
| 170 | r_sin.* = @floatCast(f80, big_sin); | ||
| 171 | r_cos.* = @floatCast(f80, big_cos); | ||
| 17 | } | 172 | } |
| 18 | 173 | ||
| 19 | pub fn __sincosx(a: f80, r_sin: *f80, r_cos: *f80) callconv(.C) void { | 174 | pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.C) void { |
| 20 | r_sin.* = sin.__sinx(a); | 175 | // TODO: more correct implementation |
| 21 | r_cos.* = cos.__cosx(a); | 176 | //return sincos_generic(f128, x, r_sin, r_cos); |
| 177 | var small_sin: f64 = undefined; | ||
| 178 | var small_cos: f64 = undefined; | ||
| 179 | sincos(@floatCast(f64, x), &small_sin, &small_cos); | ||
| 180 | r_sin.* = small_sin; | ||
| 181 | r_cos.* = small_cos; | ||
| 22 | } | 182 | } |
| 23 | 183 | ||
| 24 | pub fn sincosq(a: f128, r_sin: *f128, r_cos: *f128) callconv(.C) void { | 184 | const rem_pio2_generic = @compileError("TODO"); |
| 25 | r_sin.* = sin.sinq(a); | 185 | |
| 26 | r_cos.* = cos.cosq(a); | 186 | /// Ported from musl sincosl.c. Needs the following dependencies to be complete: |
| 187 | /// * rem_pio2_generic ported from __rem_pio2l.c | ||
| 188 | /// * trig.sin_generic ported from __sinl.c | ||
| 189 | /// * trig.cos_generic ported from __cosl.c | ||
| 190 | inline fn sincos_generic(comptime F: type, x: F, r_sin: *F, r_cos: *F) void { | ||
| 191 | const sc1pio4: F = 1.0 * math.pi / 4.0; | ||
| 192 | const bits = @typeInfo(F).Float.bits; | ||
| 193 | const I = std.meta.Int(.unsigned, bits); | ||
| 194 | const ix = @bitCast(I, x) & (math.maxInt(I) >> 1); | ||
| 195 | const se = @truncate(u16, ix >> (bits - 16)); | ||
| 196 | |||
| 197 | if (se == 0x7fff) { | ||
| 198 | const result = x - x; | ||
| 199 | r_sin.* = result; | ||
| 200 | r_cos.* = result; | ||
| 201 | return; | ||
| 202 | } | ||
| 203 | |||
| 204 | if (@bitCast(F, ix) < sc1pio4) { | ||
| 205 | if (se < 0x3fff - math.floatFractionalBits(F) - 1) { | ||
| 206 | // raise underflow if subnormal | ||
| 207 | if (se == 0) { | ||
| 208 | math.doNotOptimizeAway(x * 0x1p-120); | ||
| 209 | } | ||
| 210 | r_sin.* = x; | ||
| 211 | // raise inexact if x!=0 | ||
| 212 | r_cos.* = 1.0 + x; | ||
| 213 | return; | ||
| 214 | } | ||
| 215 | r_sin.* = trig.sin_generic(F, x, 0, 0); | ||
| 216 | r_cos.* = trig.cos_generic(F, x, 0); | ||
| 217 | return; | ||
| 218 | } | ||
| 219 | |||
| 220 | var y: [2]F = undefined; | ||
| 221 | const n = rem_pio2_generic(F, x, &y); | ||
| 222 | const s = trig.sin_generic(F, y[0], y[1], 1); | ||
| 223 | const c = trig.cos_generic(F, y[0], y[1]); | ||
| 224 | switch (n & 3) { | ||
| 225 | 0 => { | ||
| 226 | r_sin.* = s; | ||
| 227 | r_cos.* = c; | ||
| 228 | }, | ||
| 229 | 1 => { | ||
| 230 | r_sin.* = c; | ||
| 231 | r_cos.* = -s; | ||
| 232 | }, | ||
| 233 | 2 => { | ||
| 234 | r_sin.* = -s; | ||
| 235 | r_cos.* = -c; | ||
| 236 | }, | ||
| 237 | else => { | ||
| 238 | r_sin.* = -c; | ||
| 239 | r_cos.* = s; | ||
| 240 | }, | ||
| 241 | } | ||
| 27 | } | 242 | } |