aboutsummaryrefslogtreecommitdiff
path: root/std/math/fmod.zig
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-06-19 14:36:33 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-06-19 14:36:33 -0400
commitc9fc8bd802f5ed52c4cc78b93f18fc5dc9b6bb7f (patch)
tree8ddb992d7c1b4ede1b6a99e32fad16c1a476e0c1 /std/math/fmod.zig
parent799c69910172a7248ab9db366e6e3a6556e7d626 (diff)
downloadzig-c9fc8bd802f5ed52c4cc78b93f18fc5dc9b6bb7f.tar.gz
zig-c9fc8bd802f5ed52c4cc78b93f18fc5dc9b6bb7f.zip
workaround for llvm bug
See #393 for details
Diffstat (limited to 'std/math/fmod.zig')
-rw-r--r--std/math/fmod.zig190
1 files changed, 0 insertions, 190 deletions
diff --git a/std/math/fmod.zig b/std/math/fmod.zig
deleted file mode 100644
index 8cc9586bc0..0000000000
--- a/std/math/fmod.zig
+++ /dev/null
@@ -1,190 +0,0 @@
-const math = @import("index.zig");
-const assert = @import("../debug.zig").assert;
-
-pub fn fmod(comptime T: type, x: T, y: T) -> T {
- switch (T) {
- f32 => @inlineCall(fmod32, x, y),
- f64 => @inlineCall(fmod64, x, y),
- else => @compileError("fmod not implemented for " ++ @typeName(T)),
- }
-}
-
-fn fmod32(x: f32, y: f32) -> f32 {
- var ux = @bitCast(u32, x);
- var uy = @bitCast(u32, y);
- var ex = i32(ux >> 23) & 0xFF;
- var ey = i32(ux >> 23) & 0xFF;
- const sx = ux & 0x80000000;
-
- if (uy << 1 == 0 or math.isNan(y) or ex == 0xFF) {
- return (x * y) / (x * y);
- }
- if (ux << 1 <= uy << 1) {
- if (ux << 1 == uy << 1) {
- return 0 * x;
- } else {
- return x;
- }
- }
-
- // normalize x and y
- if (ex == 0) {
- var i = ux << 9;
- while (i >> 31 == 0) : (i <<= 1) {
- ex -= 1;
- }
- ux <<= u32(-ex + 1);
- } else {
- ux &= @maxValue(u32) >> 9;
- ux |= 1 << 23;
- }
-
- if (ey == 0) {
- var i = uy << 9;
- while (i >> 31 == 0) : (i <<= 1) {
- ey -= 1;
- }
- uy <<= u32(-ey + 1);
- } else {
- uy &= @maxValue(u32) >> 9;
- uy |= 1 << 23;
- }
-
- // x mod y
- while (ex > ey) : (ex -= 1) {
- const i = ux - uy;
- if (i >> 31 == 0) {
- if (i == 0) {
- return 0 * x;
- }
- ux = i;
- }
- ux <<= 1;
- }
- {
- const i = ux - uy;
- if (i >> 31 == 0) {
- if (i == 0) {
- return 0 * x;
- }
- ux = i;
- }
- }
-
- while (ux >> 23 == 0) : (ux <<= 1) {
- ex -= 1;
- }
-
- // scale result up
- if (ex > 0) {
- ux -= 1 << 23;
- ux |= u32(ex) << 23;
- } else {
- ux >>= u32(-ex + 1);
- }
-
- ux |= sx;
- @bitCast(f32, ux)
-}
-
-fn fmod64(x: f64, y: f64) -> f64 {
- var ux = @bitCast(u64, x);
- var uy = @bitCast(u64, y);
- var ex = i32(ux >> 52) & 0x7FF;
- var ey = i32(ux >> 52) & 0x7FF;
- const sx = ux >> 63;
-
- if (uy << 1 == 0 or math.isNan(y) or ex == 0x7FF) {
- return (x * y) / (x * y);
- }
- if (ux << 1 <= uy << 1) {
- if (ux << 1 == uy << 1) {
- return 0 * x;
- } else {
- return x;
- }
- }
-
- // normalize x and y
- if (ex == 0) {
- var i = ux << 12;
- while (i >> 63 == 0) : (i <<= 1) {
- ex -= 1;
- }
- ux <<= u64(-ex + 1);
- } else {
- ux &= @maxValue(u64) >> 12;
- ux |= 1 << 52;
- }
-
- if (ey == 0) {
- var i = uy << 12;
- while (i >> 63 == 0) : (i <<= 1) {
- ey -= 1;
- }
- uy <<= u64(-ey + 1);
- } else {
- uy &= @maxValue(u64) >> 12;
- uy |= 1 << 52;
- }
-
- // x mod y
- while (ex > ey) : (ex -= 1) {
- const i = ux - uy;
- if (i >> 63 == 0) {
- if (i == 0) {
- return 0 * x;
- }
- ux = i;
- }
- ux <<= 1;
- }
- {
- const i = ux - uy;
- if (i >> 63 == 0) {
- if (i == 0) {
- return 0 * x;
- }
- ux = i;
- }
- }
-
- while (ux >> 52 == 0) : (ux <<= 1) {
- ex -= 1;
- }
-
- // scale result up
- if (ex > 0) {
- ux -= 1 << 52;
- ux |= u64(ex) << 52;
- } else {
- ux >>= u64(-ex + 1);
- }
-
- ux |= sx << 63;
- @bitCast(f64, ux)
-}
-
-// duplicate symbol clash with `fmod` test name
-test "fmod_" {
- assert(fmod(f32, 1.3, 2.5) == fmod32(1.3, 2.5));
- assert(fmod(f64, 1.3, 2.5) == fmod64(1.3, 2.5));
-}
-
-test "fmod32" {
- const epsilon = 0.000001;
-
- assert(math.approxEq(f32, fmod32(5.2, 2.0), 1.2, epsilon));
- assert(math.approxEq(f32, fmod32(18.5, 4.2), 1.7, epsilon));
- assert(math.approxEq(f32, fmod32(23, 48.34), 23.0, epsilon));
- assert(math.approxEq(f32, fmod32(123.340890, 2398.2314), 123.340889, epsilon));
-}
-
-test "fmod64" {
- const epsilon = 0.000001;
-
- assert(math.approxEq(f64, fmod64(5.2, 2.0), 1.2, epsilon));
- assert(math.approxEq(f64, fmod64(18.5, 4.2), 1.7, epsilon));
- assert(math.approxEq(f64, fmod64(23, 48.34), 23.0, epsilon));
- assert(math.approxEq(f64, fmod64(123.340890, 2398.2314), 123.340889, epsilon));
-}