aboutsummaryrefslogtreecommitdiff
path: root/std/math/trunc.zig
diff options
context:
space:
mode:
authorMarc Tiehuis <marctiehuis@gmail.com>2017-06-16 20:26:10 +1200
committerMarc Tiehuis <marctiehuis@gmail.com>2017-06-16 20:32:31 +1200
commit4c16f9a3c35b23b9917f2a27b91ba8cd20e6fd82 (patch)
tree778f0f06734f7dc17e9269ee1cf5b513f7b504c0 /std/math/trunc.zig
parent865b53f2860405a718262abf9a794d2bf9529dbc (diff)
downloadzig-4c16f9a3c35b23b9917f2a27b91ba8cd20e6fd82.tar.gz
zig-4c16f9a3c35b23b9917f2a27b91ba8cd20e6fd82.zip
Add math library
This covers the majority of the functions as covered by the C99 specification for a math library. Code is adapted primarily from musl libc, with the pow and standard trigonometric functions adapted from the Go stdlib. Changes: - Remove assert expose in index and import as needed. - Add float log function and merge with existing base 2 integer implementation. See https://github.com/tiehuis/zig-fmath. See #374.
Diffstat (limited to 'std/math/trunc.zig')
-rw-r--r--std/math/trunc.zig70
1 files changed, 70 insertions, 0 deletions
diff --git a/std/math/trunc.zig b/std/math/trunc.zig
new file mode 100644
index 0000000000..8c2c1b0496
--- /dev/null
+++ b/std/math/trunc.zig
@@ -0,0 +1,70 @@
+const math = @import("index.zig");
+const assert = @import("../debug.zig").assert;
+
+pub fn trunc(x: var) -> @typeOf(x) {
+ const T = @typeOf(x);
+ switch (T) {
+ f32 => @inlineCall(trunc32, x),
+ f64 => @inlineCall(trunc64, x),
+ else => @compileError("trunc not implemented for " ++ @typeName(T)),
+ }
+}
+
+fn trunc32(x: f32) -> f32 {
+ const u = @bitCast(u32, x);
+ var e = i32(((u >> 23) & 0xFF)) - 0x7F + 9;
+ var m: u32 = undefined;
+
+ if (e >= 23 + 9) {
+ return x;
+ }
+ if (e < 9) {
+ e = 1;
+ }
+
+ m = @maxValue(u32) >> u32(e);
+ if (u & m == 0) {
+ x
+ } else {
+ math.forceEval(x + 0x1p120);
+ @bitCast(f32, u & ~m)
+ }
+}
+
+fn trunc64(x: f64) -> f64 {
+ const u = @bitCast(u64, x);
+ var e = i32(((u >> 52) & 0x7FF)) - 0x3FF + 12;
+ var m: u64 = undefined;
+
+ if (e >= 52 + 12) {
+ return x;
+ }
+ if (e < 12) {
+ e = 1;
+ }
+
+ m = @maxValue(u64) >> u64(e);
+ if (u & m == 0) {
+ x
+ } else {
+ math.forceEval(x + 0x1p120);
+ @bitCast(f64, u & ~m)
+ }
+}
+
+test "trunc" {
+ assert(trunc(f32(1.3)) == trunc32(1.3));
+ assert(trunc(f64(1.3)) == trunc64(1.3));
+}
+
+test "trunc32" {
+ assert(trunc32(1.3) == 1.0);
+ assert(trunc32(-1.3) == -1.0);
+ assert(trunc32(0.2) == 0.0);
+}
+
+test "trunc64" {
+ assert(trunc64(1.3) == 1.0);
+ assert(trunc64(-1.3) == -1.0);
+ assert(trunc64(0.2) == 0.0);
+}