aboutsummaryrefslogtreecommitdiff
path: root/std/math/exp.zig
diff options
context:
space:
mode:
Diffstat (limited to 'std/math/exp.zig')
-rw-r--r--std/math/exp.zig47
1 files changed, 24 insertions, 23 deletions
diff --git a/std/math/exp.zig b/std/math/exp.zig
index 4032930a43..d6185d4f0b 100644
--- a/std/math/exp.zig
+++ b/std/math/exp.zig
@@ -6,6 +6,7 @@
const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
+const builtin = @import("builtin");
pub fn exp(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -17,16 +18,18 @@ pub fn exp(x: var) @typeOf(x) {
}
fn exp32(x_: f32) f32 {
- const half = []f32 { 0.5, -0.5 };
+ @setFloatMode(this, builtin.FloatMode.Strict);
+
+ const half = []f32{ 0.5, -0.5 };
const ln2hi = 6.9314575195e-1;
const ln2lo = 1.4286067653e-6;
- const invln2 = 1.4426950216e+0;
+ const invln2 = 1.4426950216e+0;
const P1 = 1.6666625440e-1;
const P2 = -2.7667332906e-3;
var x = x_;
var hx = @bitCast(u32, x);
- const sign = i32(hx >> 31);
+ const sign = @intCast(i32, hx >> 31);
hx &= 0x7FFFFFFF;
if (math.isNan(x)) {
@@ -44,7 +47,7 @@ fn exp32(x_: f32) f32 {
return x * 0x1.0p127;
}
if (sign != 0) {
- math.forceEval(-0x1.0p-149 / x); // overflow
+ math.forceEval(-0x1.0p-149 / x); // overflow
// x <= -103.972084
if (hx >= 0x42CFF1B5) {
return 0;
@@ -60,13 +63,12 @@ fn exp32(x_: f32) f32 {
if (hx > 0x3EB17218) {
// |x| > 1.5 * ln2
if (hx > 0x3F851592) {
- k = i32(invln2 * x + half[usize(sign)]);
- }
- else {
+ k = @floatToInt(i32, invln2 * x + half[@intCast(usize, sign)]);
+ } else {
k = 1 - sign - sign;
}
- const fk = f32(k);
+ const fk = @intToFloat(f32, k);
hi = x - fk * ln2hi;
lo = fk * ln2lo;
x = hi - lo;
@@ -76,8 +78,7 @@ fn exp32(x_: f32) f32 {
k = 0;
hi = x;
lo = 0;
- }
- else {
+ } else {
math.forceEval(0x1.0p127 + x); // inexact
return 1 + x;
}
@@ -94,20 +95,22 @@ fn exp32(x_: f32) f32 {
}
fn exp64(x_: f64) f64 {
- const half = []const f64 { 0.5, -0.5 };
+ @setFloatMode(this, builtin.FloatMode.Strict);
+
+ const half = []const f64{ 0.5, -0.5 };
const ln2hi: f64 = 6.93147180369123816490e-01;
const ln2lo: f64 = 1.90821492927058770002e-10;
const invln2: f64 = 1.44269504088896338700e+00;
- const P1: f64 = 1.66666666666666019037e-01;
- const P2: f64 = -2.77777777770155933842e-03;
- const P3: f64 = 6.61375632143793436117e-05;
- const P4: f64 = -1.65339022054652515390e-06;
- const P5: f64 = 4.13813679705723846039e-08;
+ const P1: f64 = 1.66666666666666019037e-01;
+ const P2: f64 = -2.77777777770155933842e-03;
+ const P3: f64 = 6.61375632143793436117e-05;
+ const P4: f64 = -1.65339022054652515390e-06;
+ const P5: f64 = 4.13813679705723846039e-08;
var x = x_;
var ux = @bitCast(u64, x);
var hx = ux >> 32;
- const sign = i32(hx >> 31);
+ const sign = @intCast(i32, hx >> 31);
hx &= 0x7FFFFFFF;
if (math.isNan(x)) {
@@ -145,13 +148,12 @@ fn exp64(x_: f64) f64 {
if (hx > 0x3EB17218) {
// |x| >= 1.5 * ln2
if (hx > 0x3FF0A2B2) {
- k = i32(invln2 * x + half[usize(sign)]);
- }
- else {
+ k = @floatToInt(i32, invln2 * x + half[@intCast(usize, sign)]);
+ } else {
k = 1 - sign - sign;
}
- const dk = f64(k);
+ const dk = @intToFloat(f64, k);
hi = x - dk * ln2hi;
lo = dk * ln2lo;
x = hi - lo;
@@ -161,8 +163,7 @@ fn exp64(x_: f64) f64 {
k = 0;
hi = x;
lo = 0;
- }
- else {
+ } else {
// inexact if x != 0
// math.forceEval(0x1.0p1023 + x);
return 1 + x;