zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

powiXf2.zig (2072B) - Raw


      1 //! a raised to integer power of b
      2 //! ported from https://github.com/llvm-mirror/compiler-rt/blob/release_80/lib/builtins/powisf2.c
      3 //! Multiplication order (left-to-right or right-to-left) does not matter for
      4 //! error propagation and this method is optimized for performance, not accuracy.
      5 
      6 const builtin = @import("builtin");
      7 const common = @import("common.zig");
      8 const std = @import("std");
      9 
     10 pub const panic = common.panic;
     11 
     12 comptime {
     13     @export(&__powihf2, .{ .name = "__powihf2", .linkage = common.linkage, .visibility = common.visibility });
     14     @export(&__powisf2, .{ .name = "__powisf2", .linkage = common.linkage, .visibility = common.visibility });
     15     @export(&__powidf2, .{ .name = "__powidf2", .linkage = common.linkage, .visibility = common.visibility });
     16     if (common.want_ppc_abi)
     17         @export(&__powitf2, .{ .name = "__powikf2", .linkage = common.linkage, .visibility = common.visibility });
     18     @export(&__powitf2, .{ .name = "__powitf2", .linkage = common.linkage, .visibility = common.visibility });
     19     @export(&__powixf2, .{ .name = "__powixf2", .linkage = common.linkage, .visibility = common.visibility });
     20 }
     21 
     22 inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT {
     23     var x_a: FT = a;
     24     var x_b: i32 = b;
     25     const is_recip: bool = b < 0;
     26     var r: FT = 1.0;
     27     while (true) {
     28         if (@as(u32, @bitCast(x_b)) & @as(u32, 1) != 0) {
     29             r *= x_a;
     30         }
     31         x_b = @divTrunc(x_b, @as(i32, 2));
     32         if (x_b == 0) break;
     33         x_a *= x_a; // Multiplication of x_a propagates the error
     34     }
     35     return if (is_recip) 1 / r else r;
     36 }
     37 
     38 pub fn __powihf2(a: f16, b: i32) callconv(.c) f16 {
     39     return powiXf2(f16, a, b);
     40 }
     41 
     42 pub fn __powisf2(a: f32, b: i32) callconv(.c) f32 {
     43     return powiXf2(f32, a, b);
     44 }
     45 
     46 pub fn __powidf2(a: f64, b: i32) callconv(.c) f64 {
     47     return powiXf2(f64, a, b);
     48 }
     49 
     50 pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 {
     51     return powiXf2(f128, a, b);
     52 }
     53 
     54 pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 {
     55     return powiXf2(f80, a, b);
     56 }
     57 
     58 test {
     59     _ = @import("powiXf2_test.zig");
     60 }