| 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/__expo2f.c |
| 5 | // https://git.musl-libc.org/cgit/musl/tree/src/math/__expo2.c |
| 6 | |
| 7 | const math = @import("../math.zig"); |
| 8 | |
| 9 | /// Returns exp(x) / 2 for x >= log(maxFloat(T)). |
| 10 | pub fn expo2(x: anytype) @TypeOf(x) { |
| 11 | const T = @TypeOf(x); |
| 12 | return switch (T) { |
| 13 | f32 => expo2f(x), |
| 14 | f64 => expo2d(x), |
| 15 | else => @compileError("expo2 not implemented for " ++ @typeName(T)), |
| 16 | }; |
| 17 | } |
| 18 | |
| 19 | fn expo2f(x: f32) f32 { |
| 20 | const k: u32 = 235; |
| 21 | const kln2 = 0x1.45C778p+7; |
| 22 | |
| 23 | const u = (0x7F + k / 2) << 23; |
| 24 | const scale = @as(f32, @bitCast(u)); |
| 25 | return @exp(x - kln2) * scale * scale; |
| 26 | } |
| 27 | |
| 28 | fn expo2d(x: f64) f64 { |
| 29 | const k: u32 = 2043; |
| 30 | const kln2 = 0x1.62066151ADD8BP+10; |
| 31 | |
| 32 | const u = (0x3FF + k / 2) << 20; |
| 33 | const scale = @as(f64, @bitCast(@as(u64, u) << 32)); |
| 34 | return @exp(x - kln2) * scale * scale; |
| 35 | } |