mirror of
https://github.com/ziglang/zig.git
synced 2025-12-20 13:13:16 +00:00
90 lines
1.9 KiB
Zig
90 lines
1.9 KiB
Zig
const assert = @import("../debug.zig").assert;
|
|
const math = @import("index.zig");
|
|
|
|
pub fn frexp(x: var, e: &i32) -> @typeOf(x) {
|
|
const T = @typeOf(x);
|
|
switch (T) {
|
|
f32 => frexp32(x, e),
|
|
f64 => frexp64(x, e),
|
|
else => @compileError("frexp not implemented for " ++ @typeName(T)),
|
|
}
|
|
}
|
|
|
|
fn frexp32(x_: f32, e: &i32) -> f32 {
|
|
var x = x_;
|
|
var y = @bitCast(u32, x);
|
|
const ee = i32(y >> 23) & 0xFF;
|
|
|
|
if (ee == 0) {
|
|
if (x != 0) {
|
|
x = frexp32(x * 0x1.0p64, e);
|
|
*e -= 64;
|
|
} else {
|
|
*e = 0;
|
|
}
|
|
return x;
|
|
} else if (ee == 0xFF) {
|
|
return x;
|
|
}
|
|
|
|
*e = ee - 0x7E;
|
|
y &= 0x807FFFFF;
|
|
y |= 0x3F000000;
|
|
@bitCast(f32, y)
|
|
}
|
|
|
|
fn frexp64(x_: f64, e: &i32) -> f64 {
|
|
var x = x_;
|
|
var y = @bitCast(u64, x);
|
|
const ee = i32(y >> 52) & 0x7FF;
|
|
|
|
if (ee == 0) {
|
|
if (x != 0) {
|
|
x = frexp64(x * 0x1.0p64, e);
|
|
*e -= 64;
|
|
} else {
|
|
*e = 0;
|
|
}
|
|
return x;
|
|
} else if (ee == 0x7FF) {
|
|
return x;
|
|
}
|
|
|
|
*e = ee - 0x3FE;
|
|
y &= 0x800FFFFFFFFFFFFF;
|
|
y |= 0x3FE0000000000000;
|
|
@bitCast(f64, y)
|
|
}
|
|
|
|
test "frexp" {
|
|
var i0: i32 = undefined;
|
|
var i1: i32 = undefined;
|
|
|
|
assert(frexp(f32(1.3), &i0) == frexp32(1.3, &i1));
|
|
assert(frexp(f64(1.3), &i0) == frexp64(1.3, &i1));
|
|
}
|
|
|
|
test "frexp32" {
|
|
const epsilon = 0.000001;
|
|
var i: i32 = undefined;
|
|
var d: f32 = undefined;
|
|
|
|
d = frexp32(1.3, &i);
|
|
assert(math.approxEq(f32, d, 0.65, epsilon) and i == 1);
|
|
|
|
d = frexp32(78.0234, &i);
|
|
assert(math.approxEq(f32, d, 0.609558, epsilon) and i == 7);
|
|
}
|
|
|
|
test "frexp64" {
|
|
const epsilon = 0.000001;
|
|
var i: i32 = undefined;
|
|
var d: f64 = undefined;
|
|
|
|
d = frexp64(1.3, &i);
|
|
assert(math.approxEq(f64, d, 0.65, epsilon) and i == 1);
|
|
|
|
d = frexp64(78.0234, &i);
|
|
assert(math.approxEq(f64, d, 0.609558, epsilon) and i == 7);
|
|
}
|