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/ › truncf.zig › trunc_f80
trunc_f80
truncf.trunc_f80
pub inline fn trunc_f80 (comptime dst_t : type , a : f80 ) dst_t
File
Code
pub inline fn trunc_f80 (comptime dst_t : type , a : f80 ) dst_t {
const dst_rep_t = @Int (.unsigned , @typeInfo (dst_t ).float .bits );
const src_sig_bits = std .math .floatMantissaBits (f80 ) - 1 ;
const dst_sig_bits = std .math .floatMantissaBits (dst_t );
const src_exp_bias = 16383 ;
const round_mask = (1 << (src_sig_bits - dst_sig_bits )) - 1 ;
const halfway = 1 << (src_sig_bits - dst_sig_bits - 1 );
const dst_bits = @typeInfo (dst_t ).float .bits ;
const dst_exp_bits = dst_bits - dst_sig_bits - 1 ;
const dst_inf_exp = (1 << dst_exp_bits ) - 1 ;
const dst_exp_bias = dst_inf_exp >> 1 ;
const underflow = src_exp_bias + 1 - dst_exp_bias ;
const overflow = src_exp_bias + dst_inf_exp - dst_exp_bias ;
const dst_qnan = 1 << (dst_sig_bits - 1 );
const dst_nan_mask = dst_qnan - 1 ;
var a_rep = std .math .F80 .fromFloat (a );
const sign = a_rep .exp & 0x8000 ;
a_rep .exp &= 0x7FFF ;
a_rep .fraction &= 0x7FFFFFFFFFFFFFFF ;
var abs_result : dst_rep_t = undefined ;
if (a_rep .exp -% underflow < a_rep .exp -% overflow ) {
// destination format. We can convert by simply right-shifting with
// rounding and adjusting the exponent.
abs_result = @as (dst_rep_t , a_rep .exp ) << dst_sig_bits ;
abs_result |= @truncate (a_rep .fraction >> (src_sig_bits - dst_sig_bits ));
abs_result -%= @as (dst_rep_t , src_exp_bias - dst_exp_bias ) << dst_sig_bits ;
const round_bits = a_rep .fraction & round_mask ;
if (round_bits > halfway ) {
abs_result += 1 ;
} else if (round_bits == halfway ) {
abs_result += abs_result & 1 ;
}
} else if (a_rep .exp == 0x7FFF and a_rep .fraction != 0 ) {
// Conjure the result by beginning with infinity, setting the qNaN
// bit and inserting the (truncated) trailing NaN field.
abs_result = @as (dst_rep_t , @intCast (dst_inf_exp )) << dst_sig_bits ;
abs_result |= dst_qnan ;
abs_result |= @intCast ((a_rep .fraction >> (src_sig_bits - dst_sig_bits )) & dst_nan_mask );
} else if (a_rep .exp >= overflow ) {
abs_result = @as (dst_rep_t , @intCast (dst_inf_exp )) << dst_sig_bits ;
} else {
// zero. The result may be a denormal or zero. Extract the exponent
// to get the shift amount for the denormalization.
const shift = src_exp_bias - dst_exp_bias - a_rep .exp ;
if (shift > src_sig_bits ) {
abs_result = 0 ;
} else {
const sticky = @intFromBool (a_rep .fraction << @intCast (shift ) != 0 );
const denormalized_significand = a_rep .fraction >> @intCast (shift ) | sticky ;
abs_result = @intCast (denormalized_significand >> (src_sig_bits - dst_sig_bits ));
const round_bits = denormalized_significand & round_mask ;
if (round_bits > halfway ) {
abs_result += 1 ;
} else if (round_bits == halfway ) {
abs_result += abs_result & 1 ;
}
}
}
const result align (@alignOf (dst_t )) = abs_result | @as (dst_rep_t , sign ) << dst_bits - 16 ;
return @bitCast (result );
}