Zig 0.17.0-dev (Split by item)
This is an example of documentation generated by
ZigDoc , an alternative to Zig's built-in
Auto Doc feature. See also
examples in other modes/formats . The project being documented here (as the example) is the Zig library itself.
Zig › compiler_rt/ › trunctfxf2.zig
trunctfxf2.zig
Index
File
Code
const math = @import ("std" ).math ;
const compiler_rt = @import ("../compiler_rt.zig" );
const symbol = compiler_rt .symbol ;
const trunc_f80 = @import ("./truncf.zig" ).trunc_f80 ;
comptime {
symbol (&__trunctfxf2 , "__trunctfxf2" );
}
pub fn __trunctfxf2 (a : f128 ) callconv (.c ) f80 {
const src_sig_bits = math .floatMantissaBits (f128 );
const dst_sig_bits = math .floatMantissaBits (f80 ) - 1 ;
// Various constants whose values follow from the type parameters.
// Any reasonable optimizer will fold and propagate all of these.
const src_bits = @typeInfo (f128 ).float .bits ;
const src_exp_bits = src_bits - src_sig_bits - 1 ;
const src_inf_exp = 0x7FFF ;
const src_inf = src_inf_exp << src_sig_bits ;
const src_sign_mask = 1 << (src_sig_bits + src_exp_bits );
const src_abs_mask = src_sign_mask - 1 ;
const round_mask = (1 << (src_sig_bits - dst_sig_bits )) - 1 ;
const halfway = 1 << (src_sig_bits - dst_sig_bits - 1 );
const a_rep = @as (u128 , @bitCast (a ));
const a_abs = a_rep & src_abs_mask ;
const sign : u16 = if (a_rep & src_sign_mask != 0 ) 0x8000 else 0 ;
const integer_bit = 1 << 63 ;
var res : math .F80 = undefined ;
if (a_abs > src_inf ) {
// Conjure the result by beginning with infinity, setting the qNaN
// bit and inserting the (truncated) trailing NaN field.
res .exp = 0x7fff ;
res .fraction = 0x8000000000000000 ;
res .fraction |= @as (u64 , @truncate (a_abs >> (src_sig_bits - dst_sig_bits )));
} else {
// destination format. We can convert by simply right-shifting with
// rounding, adding the explicit integer bit, and adjusting the exponent
res .fraction = @as (u64 , @truncate (a_abs >> (src_sig_bits - dst_sig_bits ))) | integer_bit ;
res .exp = @truncate (a_abs >> src_sig_bits );
const round_bits = a_abs & round_mask ;
if (round_bits > halfway ) {
const ov = @addWithOverflow (res .fraction , 1 );
res .fraction = ov [0 ];
res .exp += ov [1 ];
res .fraction |= @as (u64 , ov [1 ]) << 63 ;
} else if (round_bits == halfway ) {
const ov = @addWithOverflow (res .fraction , res .fraction & 1 );
res .fraction = ov [0 ];
res .exp += ov [1 ];
res .fraction |= @as (u64 , ov [1 ]) << 63 ;
}
if (res .exp == 0 ) res .fraction &= ~@as (u64 , integer_bit );
}
res .exp |= sign ;
return res .toFloat ();
}