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 }