@zigc/lib 0.16.0-dev.3091 → 0.16.0-dev.3128
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/c/math.zig +121 -30
- package/compiler/build_runner.zig +1 -0
- package/compiler/test_runner.zig +191 -59
- package/compiler_rt/cos.zig +141 -52
- package/compiler_rt/long_double.zig +37 -0
- package/compiler_rt/rem_pio2l.zig +173 -0
- package/compiler_rt/sin.zig +140 -55
- package/compiler_rt/sincos.zig +279 -72
- package/compiler_rt/tan.zig +118 -47
- package/compiler_rt/trig.zig +256 -6
- package/fuzzer.zig +855 -307
- package/package.json +1 -1
- package/std/Build/Fuzz.zig +6 -19
- package/std/Build/Step/Run.zig +530 -68
- package/std/Build/abi.zig +39 -7
- package/std/Build.zig +3 -0
- package/std/compress/flate/Compress.zig +3 -3
- package/std/debug/Info.zig +4 -0
- package/std/heap/ArenaAllocator.zig +145 -154
- package/std/mem/Allocator.zig +4 -5
- package/std/mem.zig +48 -0
- package/std/priority_dequeue.zig +13 -12
- package/std/priority_queue.zig +5 -4
- package/std/zig/Client.zig +8 -3
- package/std/zig/Server.zig +26 -0
- package/libc/mingw/complex/cabs.c +0 -48
- package/libc/mingw/complex/cabsf.c +0 -48
- package/libc/mingw/complex/cacos.c +0 -50
- package/libc/mingw/complex/cacosf.c +0 -50
- package/libc/mingw/complex/carg.c +0 -48
- package/libc/mingw/complex/cargf.c +0 -48
- package/libc/mingw/complex/casin.c +0 -50
- package/libc/mingw/complex/casinf.c +0 -50
- package/libc/mingw/complex/catan.c +0 -50
- package/libc/mingw/complex/catanf.c +0 -50
- package/libc/mingw/complex/ccos.c +0 -50
- package/libc/mingw/complex/ccosf.c +0 -50
- package/libc/mingw/complex/cexp.c +0 -48
- package/libc/mingw/complex/cexpf.c +0 -48
- package/libc/mingw/complex/cimag.c +0 -48
- package/libc/mingw/complex/cimagf.c +0 -48
- package/libc/mingw/complex/clog.c +0 -48
- package/libc/mingw/complex/clog10.c +0 -49
- package/libc/mingw/complex/clog10f.c +0 -49
- package/libc/mingw/complex/clogf.c +0 -48
- package/libc/mingw/complex/conj.c +0 -48
- package/libc/mingw/complex/conjf.c +0 -48
- package/libc/mingw/complex/cpow.c +0 -48
- package/libc/mingw/complex/cpowf.c +0 -48
- package/libc/mingw/complex/cproj.c +0 -48
- package/libc/mingw/complex/cprojf.c +0 -48
- package/libc/mingw/complex/creal.c +0 -48
- package/libc/mingw/complex/crealf.c +0 -48
- package/libc/mingw/complex/csin.c +0 -50
- package/libc/mingw/complex/csinf.c +0 -50
- package/libc/mingw/complex/csqrt.c +0 -48
- package/libc/mingw/complex/csqrtf.c +0 -48
- package/libc/mingw/complex/ctan.c +0 -50
- package/libc/mingw/complex/ctanf.c +0 -50
- package/libc/mingw/math/arm/s_rint.c +0 -86
- package/libc/mingw/math/arm/s_rintf.c +0 -51
- package/libc/mingw/math/arm/sincos.S +0 -30
- package/libc/mingw/math/arm-common/sincosl.c +0 -13
- package/libc/mingw/math/arm64/rint.c +0 -12
- package/libc/mingw/math/arm64/rintf.c +0 -12
- package/libc/mingw/math/arm64/sincos.S +0 -32
- package/libc/mingw/math/bsd_private_base.h +0 -148
- package/libc/mingw/math/frexpf.c +0 -13
- package/libc/mingw/math/frexpl.c +0 -71
- package/libc/mingw/math/x86/acosf.c +0 -29
- package/libc/mingw/math/x86/atanf.c +0 -23
- package/libc/mingw/math/x86/atanl.c +0 -18
- package/libc/mingw/math/x86/cos.def.h +0 -65
- package/libc/mingw/math/x86/cosl.c +0 -46
- package/libc/mingw/math/x86/cosl_internal.S +0 -55
- package/libc/mingw/math/x86/ldexp.c +0 -23
- package/libc/mingw/math/x86/scalbn.S +0 -41
- package/libc/mingw/math/x86/scalbnf.S +0 -40
- package/libc/mingw/math/x86/sin.def.h +0 -65
- package/libc/mingw/math/x86/sinl.c +0 -46
- package/libc/mingw/math/x86/sinl_internal.S +0 -58
- package/libc/mingw/math/x86/tanl.S +0 -62
- package/libc/mingw/misc/btowc.c +0 -28
- package/libc/mingw/misc/wcstof.c +0 -66
- package/libc/mingw/misc/wcstoimax.c +0 -132
- package/libc/mingw/misc/wcstoumax.c +0 -126
- package/libc/mingw/misc/wctob.c +0 -29
- package/libc/mingw/misc/winbs_uint64.c +0 -6
- package/libc/mingw/misc/winbs_ulong.c +0 -6
- package/libc/mingw/misc/winbs_ushort.c +0 -6
- package/libc/mingw/stdio/_Exit.c +0 -10
- package/libc/mingw/stdio/_findfirst64i32.c +0 -21
- package/libc/mingw/stdio/_findnext64i32.c +0 -21
- package/libc/mingw/stdio/_fstat64i32.c +0 -37
- package/libc/mingw/stdio/_stat64i32.c +0 -37
- package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
- package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
- package/libc/mingw/stdio/_wstat64i32.c +0 -37
- package/libc/musl/src/legacy/valloc.c +0 -8
- package/libc/musl/src/math/__cosl.c +0 -96
- package/libc/musl/src/math/__sinl.c +0 -78
- package/libc/musl/src/math/__tanl.c +0 -143
- package/libc/musl/src/math/aarch64/lrint.c +0 -10
- package/libc/musl/src/math/aarch64/lrintf.c +0 -10
- package/libc/musl/src/math/aarch64/rintf.c +0 -7
- package/libc/musl/src/math/cosl.c +0 -39
- package/libc/musl/src/math/exp_data.c +0 -182
- package/libc/musl/src/math/exp_data.h +0 -26
- package/libc/musl/src/math/finite.c +0 -7
- package/libc/musl/src/math/finitef.c +0 -7
- package/libc/musl/src/math/frexp.c +0 -23
- package/libc/musl/src/math/frexpf.c +0 -23
- package/libc/musl/src/math/frexpl.c +0 -29
- package/libc/musl/src/math/i386/lrint.c +0 -8
- package/libc/musl/src/math/i386/lrintf.c +0 -8
- package/libc/musl/src/math/i386/rintf.c +0 -7
- package/libc/musl/src/math/lrint.c +0 -72
- package/libc/musl/src/math/lrintf.c +0 -8
- package/libc/musl/src/math/pow_data.c +0 -180
- package/libc/musl/src/math/pow_data.h +0 -22
- package/libc/musl/src/math/powerpc64/lrint.c +0 -16
- package/libc/musl/src/math/powerpc64/lrintf.c +0 -16
- package/libc/musl/src/math/rintf.c +0 -30
- package/libc/musl/src/math/s390x/rintf.c +0 -15
- package/libc/musl/src/math/sincosl.c +0 -60
- package/libc/musl/src/math/sinl.c +0 -41
- package/libc/musl/src/math/tanl.c +0 -29
- package/libc/musl/src/math/x32/lrint.s +0 -5
- package/libc/musl/src/math/x32/lrintf.s +0 -5
- package/libc/musl/src/math/x86_64/lrint.c +0 -8
- package/libc/musl/src/math/x86_64/lrintf.c +0 -8
- package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
package/compiler_rt/cos.zig
CHANGED
|
@@ -1,19 +1,30 @@
|
|
|
1
|
+
//! Ported from musl, which is licensed under the MIT license:
|
|
2
|
+
//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
|
|
3
|
+
//!
|
|
4
|
+
//! https://git.musl-libc.org/cgit/musl/tree/src/math/cosf.c
|
|
5
|
+
//! https://git.musl-libc.org/cgit/musl/tree/src/math/cos.c
|
|
6
|
+
//! https://git.musl-libc.org/cgit/musl/tree/src/math/cosl.c
|
|
7
|
+
|
|
1
8
|
const std = @import("std");
|
|
2
9
|
const math = std.math;
|
|
3
10
|
const mem = std.mem;
|
|
4
11
|
const expect = std.testing.expect;
|
|
12
|
+
const expectApproxEqAbs = std.testing.expectApproxEqAbs;
|
|
5
13
|
|
|
6
14
|
const compiler_rt = @import("../compiler_rt.zig");
|
|
7
15
|
const symbol = @import("../compiler_rt.zig").symbol;
|
|
8
16
|
const trig = @import("trig.zig");
|
|
9
17
|
const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
|
|
10
18
|
const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
|
|
19
|
+
const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
|
|
20
|
+
const ld = @import("long_double.zig");
|
|
11
21
|
|
|
12
22
|
comptime {
|
|
13
|
-
symbol(&
|
|
23
|
+
symbol(&cosh, "__cosh");
|
|
24
|
+
symbol(&cosl, "__cosl");
|
|
14
25
|
symbol(&cosf, "cosf");
|
|
15
26
|
symbol(&cos, "cos");
|
|
16
|
-
symbol(&
|
|
27
|
+
symbol(&cosx, "__cosx");
|
|
17
28
|
if (compiler_rt.want_ppc_abi) {
|
|
18
29
|
symbol(&cosq, "cosf128");
|
|
19
30
|
}
|
|
@@ -21,7 +32,7 @@ comptime {
|
|
|
21
32
|
symbol(&cosl, "cosl");
|
|
22
33
|
}
|
|
23
34
|
|
|
24
|
-
pub fn
|
|
35
|
+
pub fn cosh(a: f16) callconv(.c) f16 {
|
|
25
36
|
// TODO: more efficient implementation
|
|
26
37
|
return @floatCast(cosf(a));
|
|
27
38
|
}
|
|
@@ -43,27 +54,27 @@ pub fn cosf(x: f32) callconv(.c) f32 {
|
|
|
43
54
|
if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120);
|
|
44
55
|
return 1.0;
|
|
45
56
|
}
|
|
46
|
-
return trig.
|
|
57
|
+
return trig.cosdf(x);
|
|
47
58
|
}
|
|
48
59
|
if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4
|
|
49
60
|
if (ix > 0x4016cbe3) { // |x| ~> 3*pi/4
|
|
50
|
-
return -trig.
|
|
61
|
+
return -trig.cosdf(if (sign) x + c2pio2 else x - c2pio2);
|
|
51
62
|
} else {
|
|
52
63
|
if (sign) {
|
|
53
|
-
return trig.
|
|
64
|
+
return trig.sindf(x + c1pio2);
|
|
54
65
|
} else {
|
|
55
|
-
return trig.
|
|
66
|
+
return trig.sindf(c1pio2 - x);
|
|
56
67
|
}
|
|
57
68
|
}
|
|
58
69
|
}
|
|
59
70
|
if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4
|
|
60
71
|
if (ix > 0x40afeddf) { // |x| ~> 7*pi/4
|
|
61
|
-
return trig.
|
|
72
|
+
return trig.cosdf(if (sign) x + c4pio2 else x - c4pio2);
|
|
62
73
|
} else {
|
|
63
74
|
if (sign) {
|
|
64
|
-
return trig.
|
|
75
|
+
return trig.sindf(-x - c3pio2);
|
|
65
76
|
} else {
|
|
66
|
-
return trig.
|
|
77
|
+
return trig.sindf(x - c3pio2);
|
|
67
78
|
}
|
|
68
79
|
}
|
|
69
80
|
}
|
|
@@ -76,10 +87,10 @@ pub fn cosf(x: f32) callconv(.c) f32 {
|
|
|
76
87
|
var y: f64 = undefined;
|
|
77
88
|
const n = rem_pio2f(x, &y);
|
|
78
89
|
return switch (n & 3) {
|
|
79
|
-
0 => trig.
|
|
80
|
-
1 => trig.
|
|
81
|
-
2 => -trig.
|
|
82
|
-
else => trig.
|
|
90
|
+
0 => trig.cosdf(y),
|
|
91
|
+
1 => trig.sindf(-y),
|
|
92
|
+
2 => -trig.cosdf(y),
|
|
93
|
+
else => trig.sindf(y),
|
|
83
94
|
};
|
|
84
95
|
}
|
|
85
96
|
|
|
@@ -94,7 +105,7 @@ pub fn cos(x: f64) callconv(.c) f64 {
|
|
|
94
105
|
if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120);
|
|
95
106
|
return 1.0;
|
|
96
107
|
}
|
|
97
|
-
return trig.
|
|
108
|
+
return trig.cos(x, 0);
|
|
98
109
|
}
|
|
99
110
|
|
|
100
111
|
// cos(Inf or NaN) is NaN
|
|
@@ -105,66 +116,144 @@ pub fn cos(x: f64) callconv(.c) f64 {
|
|
|
105
116
|
var y: [2]f64 = undefined;
|
|
106
117
|
const n = rem_pio2(x, &y);
|
|
107
118
|
return switch (n & 3) {
|
|
108
|
-
0 => trig.
|
|
109
|
-
1 => -trig.
|
|
110
|
-
2 => -trig.
|
|
111
|
-
else => trig.
|
|
119
|
+
0 => trig.cos(y[0], y[1]),
|
|
120
|
+
1 => -trig.sin(y[0], y[1], 1),
|
|
121
|
+
2 => -trig.cos(y[0], y[1]),
|
|
122
|
+
else => trig.sin(y[0], y[1], 1),
|
|
112
123
|
};
|
|
113
124
|
}
|
|
114
125
|
|
|
115
|
-
pub fn
|
|
116
|
-
|
|
117
|
-
|
|
126
|
+
pub fn cosx(x: f80) callconv(.c) f80 {
|
|
127
|
+
const se = ld.signExponent(x) & 0x7fff;
|
|
128
|
+
if (se == 0x7fff) {
|
|
129
|
+
return x - x;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (@abs(x) < trig.pi_4) {
|
|
133
|
+
if (se < 0x3fff - math.floatMantissaBits(f80)) {
|
|
134
|
+
// raise inexact if x!=0
|
|
135
|
+
return 1.0 + x;
|
|
136
|
+
}
|
|
137
|
+
return trig.cosx(x, 0.0);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
var y: [2]f80 = undefined;
|
|
141
|
+
const n = rem_pio2l(f80, x, &y);
|
|
142
|
+
return switch (n & 3) {
|
|
143
|
+
0 => trig.cosx(y[0], y[1]),
|
|
144
|
+
1 => -trig.sinx(y[0], y[1], 1),
|
|
145
|
+
2 => -trig.cosx(y[0], y[1]),
|
|
146
|
+
else => trig.sinx(y[0], y[1], 1),
|
|
147
|
+
};
|
|
118
148
|
}
|
|
119
149
|
|
|
120
|
-
pub fn cosq(
|
|
121
|
-
|
|
122
|
-
|
|
150
|
+
pub fn cosq(x: f128) callconv(.c) f128 {
|
|
151
|
+
const se = ld.signExponent(x) & 0x7fff;
|
|
152
|
+
if (se == 0x7fff) {
|
|
153
|
+
return x - x;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (@abs(x) < trig.pi_4) {
|
|
157
|
+
if (se < 0x3fff - math.floatMantissaBits(f128)) {
|
|
158
|
+
// raise inexact if x!=0
|
|
159
|
+
return 1.0 + x;
|
|
160
|
+
}
|
|
161
|
+
return trig.cosq(x, 0.0);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
var y: [2]f128 = undefined;
|
|
165
|
+
const n = rem_pio2l(f128, x, &y);
|
|
166
|
+
return switch (n & 3) {
|
|
167
|
+
0 => trig.cosq(y[0], y[1]),
|
|
168
|
+
1 => -trig.sinq(y[0], y[1], 1),
|
|
169
|
+
2 => -trig.cosq(y[0], y[1]),
|
|
170
|
+
else => trig.sinq(y[0], y[1], 1),
|
|
171
|
+
};
|
|
123
172
|
}
|
|
124
173
|
|
|
125
174
|
pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble {
|
|
126
175
|
switch (@typeInfo(c_longdouble).float.bits) {
|
|
127
|
-
16 => return
|
|
176
|
+
16 => return cosh(x),
|
|
128
177
|
32 => return cosf(x),
|
|
129
178
|
64 => return cos(x),
|
|
130
|
-
80 => return
|
|
179
|
+
80 => return cosx(x),
|
|
131
180
|
128 => return cosq(x),
|
|
132
181
|
else => @compileError("unreachable"),
|
|
133
182
|
}
|
|
134
183
|
}
|
|
135
184
|
|
|
136
|
-
|
|
137
|
-
const
|
|
185
|
+
fn testCosSpecial(comptime T: type) !void {
|
|
186
|
+
const f = switch (T) {
|
|
187
|
+
f32 => cosf,
|
|
188
|
+
f64 => cos,
|
|
189
|
+
f80 => cosx,
|
|
190
|
+
f128 => cosq,
|
|
191
|
+
else => @compileError("unimplemented"),
|
|
192
|
+
};
|
|
138
193
|
|
|
139
|
-
try expect(
|
|
140
|
-
try expect(
|
|
141
|
-
try expect(math.
|
|
142
|
-
try expect(math.
|
|
143
|
-
try expect(math.
|
|
144
|
-
try expect(math.approxEqAbs(f32, cosf(37.45), 0.969132, epsilon));
|
|
145
|
-
try expect(math.approxEqAbs(f32, cosf(89.123), 0.400798, epsilon));
|
|
194
|
+
try expect(f(0.0) == 1.0);
|
|
195
|
+
try expect(f(-0.0) == 1.0);
|
|
196
|
+
try expect(math.isNan(f(math.inf(T))));
|
|
197
|
+
try expect(math.isNan(f(-math.inf(T))));
|
|
198
|
+
try expect(math.isNan(f(math.nan(T))));
|
|
146
199
|
}
|
|
147
200
|
|
|
148
|
-
test "
|
|
149
|
-
const epsilon =
|
|
150
|
-
|
|
151
|
-
try
|
|
152
|
-
try
|
|
153
|
-
try
|
|
154
|
-
try
|
|
155
|
-
try
|
|
156
|
-
try
|
|
157
|
-
try expect(math.approxEqAbs(f64, cos(89.123), 0.40080, epsilon));
|
|
201
|
+
test "cos32.normal" {
|
|
202
|
+
const epsilon = math.floatEps(f32);
|
|
203
|
+
try expectApproxEqAbs(@as(f32, 1.0), cosf(0.0), epsilon);
|
|
204
|
+
try expectApproxEqAbs(@as(f32, 0.9800666), cosf(0.2), epsilon);
|
|
205
|
+
try expectApproxEqAbs(@as(f32, 0.6276231), cosf(0.8923), epsilon);
|
|
206
|
+
try expectApproxEqAbs(@as(f32, 0.0707372), cosf(1.5), epsilon);
|
|
207
|
+
try expectApproxEqAbs(@as(f32, 0.0707372), cosf(-1.5), epsilon);
|
|
208
|
+
try expectApproxEqAbs(@as(f32, 0.96913195), cosf(37.45), epsilon);
|
|
209
|
+
try expectApproxEqAbs(@as(f32, 0.40079966), cosf(89.123), epsilon);
|
|
158
210
|
}
|
|
159
211
|
|
|
160
212
|
test "cos32.special" {
|
|
161
|
-
try
|
|
162
|
-
|
|
163
|
-
|
|
213
|
+
try testCosSpecial(f32);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
test "cos64.normal" {
|
|
217
|
+
const epsilon = math.floatEps(f64);
|
|
218
|
+
try expectApproxEqAbs(@as(f64, 1.0), cos(0.0), epsilon);
|
|
219
|
+
try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos(0.2), epsilon);
|
|
220
|
+
try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos(0.8923), epsilon);
|
|
221
|
+
try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(1.5), epsilon);
|
|
222
|
+
try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(-1.5), epsilon);
|
|
223
|
+
try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos(37.45), epsilon);
|
|
224
|
+
try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos(89.123), epsilon);
|
|
164
225
|
}
|
|
165
226
|
|
|
166
227
|
test "cos64.special" {
|
|
167
|
-
try
|
|
168
|
-
|
|
169
|
-
|
|
228
|
+
try testCosSpecial(f64);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
test "cos80.normal" {
|
|
232
|
+
const epsilon = math.floatEps(f80);
|
|
233
|
+
try expectApproxEqAbs(@as(f80, 1.0), cosx(0.0), epsilon);
|
|
234
|
+
try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cosx(0.2), epsilon);
|
|
235
|
+
try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cosx(0.8923), epsilon);
|
|
236
|
+
try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(1.5), epsilon);
|
|
237
|
+
try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(-1.5), epsilon);
|
|
238
|
+
try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cosx(37.45), epsilon);
|
|
239
|
+
try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cosx(89.123), epsilon);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
test "cos80.special" {
|
|
243
|
+
try testCosSpecial(f80);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
test "cos128.normal" {
|
|
247
|
+
const epsilon = math.floatEps(f128);
|
|
248
|
+
try expectApproxEqAbs(@as(f128, 1.0), cosq(0.0), epsilon);
|
|
249
|
+
try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cosq(0.2), epsilon);
|
|
250
|
+
try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cosq(0.8923), epsilon);
|
|
251
|
+
try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(1.5), epsilon);
|
|
252
|
+
try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(-1.5), epsilon);
|
|
253
|
+
try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cosq(37.45), epsilon);
|
|
254
|
+
try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cosq(89.123), epsilon);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
test "cos128.special" {
|
|
258
|
+
try testCosSpecial(f128);
|
|
170
259
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//! Utilities for dealing with the `long double` type (`f80` or `f128`)
|
|
2
|
+
|
|
3
|
+
const std = @import("std");
|
|
4
|
+
|
|
5
|
+
pub const U80 = std.meta.Int(.unsigned, 80);
|
|
6
|
+
|
|
7
|
+
/// Returns the sign + exponent bits of a `long double`
|
|
8
|
+
pub fn signExponent(x: anytype) u16 {
|
|
9
|
+
const T = @TypeOf(x);
|
|
10
|
+
switch (T) {
|
|
11
|
+
f80 => {
|
|
12
|
+
const bits: U80 = @bitCast(x);
|
|
13
|
+
return @intCast(bits >> 64);
|
|
14
|
+
},
|
|
15
|
+
f128 => {
|
|
16
|
+
const bits: u128 = @bitCast(x);
|
|
17
|
+
return @intCast(bits >> 112);
|
|
18
|
+
},
|
|
19
|
+
else => @compileError("`signExponent` supports only `f80` and `f128`, got: " ++ @typeName(T)),
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// Takes the top 16 bits of a `long double`'s mantissa
|
|
24
|
+
pub fn mantissaTop(x: anytype) u16 {
|
|
25
|
+
const T = @TypeOf(x);
|
|
26
|
+
switch (T) {
|
|
27
|
+
f80 => {
|
|
28
|
+
const bits: U80 = @bitCast(x);
|
|
29
|
+
return @intCast((bits >> 48) & 0xFFFF);
|
|
30
|
+
},
|
|
31
|
+
f128 => {
|
|
32
|
+
const bits: u128 = @bitCast(x);
|
|
33
|
+
return @intCast((bits >> 96) & 0xFFFF);
|
|
34
|
+
},
|
|
35
|
+
else => @compileError("`mantissaTop` supports only `f80` and `f128`, got: " ++ @typeName(T)),
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// Ported from musl, which is licensed under the MIT license:
|
|
2
|
+
// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
|
|
3
|
+
//
|
|
4
|
+
// https://git.musl-libc.org/cgit/musl/tree/src/math/__rem_pio2l.c
|
|
5
|
+
|
|
6
|
+
const std = @import("std");
|
|
7
|
+
const math = std.math;
|
|
8
|
+
|
|
9
|
+
const ld = @import("long_double.zig");
|
|
10
|
+
const rem_pio2_large = @import("rem_pio2_large.zig").rem_pio2_large;
|
|
11
|
+
|
|
12
|
+
pub fn rem_pio2l(comptime T: type, x: T, y: *[2]T) i32 {
|
|
13
|
+
const impl = switch (T) {
|
|
14
|
+
f80 => struct {
|
|
15
|
+
const round1: i8 = 22;
|
|
16
|
+
const round2: i8 = 61;
|
|
17
|
+
const nx: i8 = 3;
|
|
18
|
+
const ny: i8 = 2;
|
|
19
|
+
|
|
20
|
+
const pio4: T = 0x1.921fb54442d1846ap-1;
|
|
21
|
+
// 64 bits of 2/pi
|
|
22
|
+
const invpio2: T = 6.36619772367581343076e-01; // 0xa2f9836e4e44152a.0p-64
|
|
23
|
+
// first 39 bits of pi/2
|
|
24
|
+
const pio2_1: f64 = 1.57079632679597125389e+00; // 0x3FF921FB, 0x54444000
|
|
25
|
+
// pi/2 - pio2_1
|
|
26
|
+
const pio2_1t: T = -1.07463465549719416346e-12; // -0x973dcb3b399d747f.0p-103
|
|
27
|
+
// second 39 bits of pi/2
|
|
28
|
+
const pio2_2: f64 = -1.07463465549783099519e-12; // -0x12e7b967674000.0p-92
|
|
29
|
+
// pi/2 - (pio2_1+pio2_2)
|
|
30
|
+
const pio2_2t: T = 6.36831716351095013979e-25; // 0xc51701b839a25205.0p-144
|
|
31
|
+
// pi/2 - (pio2_1+pio2_2+pio2_3)
|
|
32
|
+
const pio2_3t: T = -2.75299651904407171810e-37; // -0xbb5bf6c7ddd660ce.0p-185
|
|
33
|
+
// third 39 bits of pi/2
|
|
34
|
+
const pio2_3: f64 = 6.36831716351370313614e-25; // 0x18a2e037074000.0p-133
|
|
35
|
+
|
|
36
|
+
fn small(x_val: T) bool {
|
|
37
|
+
const se = ld.signExponent(x_val);
|
|
38
|
+
const top = ld.mantissaTop(x_val);
|
|
39
|
+
const lhs = (@as(u32, se & 0x7fff) << 16) | top;
|
|
40
|
+
const rhs: u32 = ((0x3fff + 25) << 16) | 0x921f >> 1 | 0x8000;
|
|
41
|
+
return lhs < rhs;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fn quobits(v: T) i32 {
|
|
45
|
+
const q: i32 = @intFromFloat(v);
|
|
46
|
+
return @intCast(@as(u32, @bitCast(q)) & 0x7fffffff);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
f128 => struct {
|
|
50
|
+
const round1: i8 = 51;
|
|
51
|
+
const round2: i8 = 119;
|
|
52
|
+
const nx: i8 = 5;
|
|
53
|
+
const ny: i8 = 3;
|
|
54
|
+
|
|
55
|
+
const pio4: T = 0x1.921fb54442d18469898cc51701b8p-1;
|
|
56
|
+
const invpio2: T = 6.3661977236758134307553505349005747e-01;
|
|
57
|
+
const pio2_1: T = 1.5707963267948966192292994253909555e+00;
|
|
58
|
+
const pio2_1t: T = 2.0222662487959507323996846200947577e-21;
|
|
59
|
+
const pio2_2: T = 2.0222662487959507323994779168837751e-21;
|
|
60
|
+
const pio2_2t: T = 2.0670321098263988236496903051604844e-43;
|
|
61
|
+
const pio2_3: T = 2.0670321098263988236499468110329591e-43;
|
|
62
|
+
const pio2_3t: T = -2.5650587247459238361625433492959285e-65;
|
|
63
|
+
|
|
64
|
+
fn small(x_val: T) bool {
|
|
65
|
+
const se = ld.signExponent(x_val);
|
|
66
|
+
const top = ld.mantissaTop(x_val);
|
|
67
|
+
const lhs = (@as(u32, se & 0x7fff) << 16) | top;
|
|
68
|
+
const rhs: u32 = ((0x3fff + 45) << 16) | 0x921f;
|
|
69
|
+
return lhs < rhs;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fn quobits(fn_val: T) i32 {
|
|
73
|
+
const q: i64 = @intFromFloat(fn_val);
|
|
74
|
+
return @intCast(@as(u64, @bitCast(q)) & 0x7fffffff);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
else => @compileError("rem_pio2l supports only f80 and f128, got: " ++ @typeName(T)),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const x_se = ld.signExponent(x);
|
|
81
|
+
const ex: i32 = @intCast(x_se & 0x7fff);
|
|
82
|
+
|
|
83
|
+
if (impl.small(x)) {
|
|
84
|
+
// rint(x/(pi/2))
|
|
85
|
+
const toint: T = 1.5 / math.floatEps(T);
|
|
86
|
+
var fn_ = x * impl.invpio2 + toint - toint;
|
|
87
|
+
var n = impl.quobits(fn_);
|
|
88
|
+
var r = x - fn_ * @as(T, impl.pio2_1);
|
|
89
|
+
var w = fn_ * impl.pio2_1t; // 1st round good to 102/180 bits
|
|
90
|
+
|
|
91
|
+
// Matters with directed rounding.
|
|
92
|
+
if (r - w < -impl.pio4) {
|
|
93
|
+
@branchHint(.unlikely);
|
|
94
|
+
n -= 1;
|
|
95
|
+
fn_ -= 1;
|
|
96
|
+
r = x - fn_ * @as(T, impl.pio2_1);
|
|
97
|
+
w = fn_ * impl.pio2_1t;
|
|
98
|
+
} else if (r - w > impl.pio4) {
|
|
99
|
+
@branchHint(.unlikely);
|
|
100
|
+
n += 1;
|
|
101
|
+
fn_ += 1;
|
|
102
|
+
r = x - fn_ * @as(T, impl.pio2_1);
|
|
103
|
+
w = fn_ * impl.pio2_1t;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
y[0] = r - w;
|
|
107
|
+
|
|
108
|
+
const ey: i32 = @intCast(ld.signExponent(y[0]) & 0x7fff);
|
|
109
|
+
if (ex - ey > impl.round1) {
|
|
110
|
+
var t = r;
|
|
111
|
+
w = fn_ * impl.pio2_2;
|
|
112
|
+
r = t - w;
|
|
113
|
+
w = fn_ * impl.pio2_2t - ((t - r) - w);
|
|
114
|
+
y[0] = r - w;
|
|
115
|
+
const ey2: i32 = @intCast(ld.signExponent(y[0]) & 0x7fff);
|
|
116
|
+
if (ex - ey2 > impl.round2) {
|
|
117
|
+
t = r;
|
|
118
|
+
w = fn_ * impl.pio2_3;
|
|
119
|
+
r = t - w;
|
|
120
|
+
w = fn_ * impl.pio2_3t - ((t - r) - w);
|
|
121
|
+
y[0] = r - w;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
y[1] = (r - y[0]) - w;
|
|
125
|
+
return n;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// all other (large) arguments
|
|
129
|
+
if (ex == 0x7fff) { // x is inf or NaN
|
|
130
|
+
y[0] = x - x;
|
|
131
|
+
y[1] = y[0];
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var z: T = math.scalbn(@abs(x), -math.ilogb(x) + 23);
|
|
136
|
+
var tx: [impl.nx]f64 = undefined;
|
|
137
|
+
var ty: [impl.ny]f64 = undefined;
|
|
138
|
+
var i: usize = 0;
|
|
139
|
+
|
|
140
|
+
while (i < impl.nx - 1) : (i += 1) {
|
|
141
|
+
tx[i] = @floatFromInt(@as(i32, @intFromFloat(z)));
|
|
142
|
+
z = (z - @as(T, tx[i])) * 0x1p24;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
tx[i] = @floatCast(z);
|
|
146
|
+
while (tx[i] == 0.0) {
|
|
147
|
+
i -= 1;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const n = rem_pio2_large(
|
|
151
|
+
tx[0..(i + 1)],
|
|
152
|
+
ty[0..impl.ny],
|
|
153
|
+
ex - 0x3fff - 23,
|
|
154
|
+
@intCast(i + 1),
|
|
155
|
+
impl.ny,
|
|
156
|
+
);
|
|
157
|
+
var w: f64 = ty[1];
|
|
158
|
+
if (impl.ny == 3) {
|
|
159
|
+
w += ty[2];
|
|
160
|
+
}
|
|
161
|
+
const r = ty[0] + w;
|
|
162
|
+
w -= r - ty[0];
|
|
163
|
+
|
|
164
|
+
if (x_se >> 15 != 0) {
|
|
165
|
+
y[0] = -@as(T, r);
|
|
166
|
+
y[1] = -@as(T, w);
|
|
167
|
+
return -n;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
y[0] = @as(T, r);
|
|
171
|
+
y[1] = @as(T, w);
|
|
172
|
+
return n;
|
|
173
|
+
}
|