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 › truncf
truncf
truncf.truncf
pub inline fn truncf (comptime dst_t : type , comptime src_t : type , a : src_t ) dst_t
File
Code
pub inline fn truncf (comptime dst_t : type , comptime src_t : type , a : src_t ) dst_t {
const src_rep_t = @Int (.unsigned , @typeInfo (src_t ).float .bits );
const dst_rep_t = @Int (.unsigned , @typeInfo (dst_t ).float .bits );
const srcSigBits = std .math .floatMantissaBits (src_t );
const dstSigBits = std .math .floatMantissaBits (dst_t );
// Any reasonable optimizer will fold and propagate all of these.
const srcBits = @typeInfo (src_t ).float .bits ;
const srcExpBits = srcBits - srcSigBits - 1 ;
const srcInfExp = (1 << srcExpBits ) - 1 ;
const srcExpBias = srcInfExp >> 1 ;
const srcMinNormal = 1 << srcSigBits ;
const srcSignificandMask = srcMinNormal - 1 ;
const srcInfinity = srcInfExp << srcSigBits ;
const srcSignMask = 1 << (srcSigBits + srcExpBits );
const srcAbsMask = srcSignMask - 1 ;
const roundMask = (1 << (srcSigBits - dstSigBits )) - 1 ;
const halfway = 1 << (srcSigBits - dstSigBits - 1 );
const srcQNaN = 1 << (srcSigBits - 1 );
const srcNaNCode = srcQNaN - 1 ;
const dstBits = @typeInfo (dst_t ).float .bits ;
const dstExpBits = dstBits - dstSigBits - 1 ;
const dstInfExp = (1 << dstExpBits ) - 1 ;
const dstExpBias = dstInfExp >> 1 ;
const underflowExponent = srcExpBias + 1 - dstExpBias ;
const overflowExponent = srcExpBias + dstInfExp - dstExpBias ;
const underflow = underflowExponent << srcSigBits ;
const overflow = overflowExponent << srcSigBits ;
const dstQNaN = 1 << (dstSigBits - 1 );
const dstNaNCode = dstQNaN - 1 ;
const aRep : src_rep_t = @bitCast (a );
const aAbs : src_rep_t = aRep & srcAbsMask ;
const sign : src_rep_t = aRep & srcSignMask ;
var absResult : dst_rep_t = undefined ;
if (aAbs -% underflow < aAbs -% overflow ) {
// destination format. We can convert by simply right-shifting with
// rounding and adjusting the exponent.
absResult = @truncate (aAbs >> (srcSigBits - dstSigBits ));
absResult -%= @as (dst_rep_t , srcExpBias - dstExpBias ) << dstSigBits ;
const roundBits : src_rep_t = aAbs & roundMask ;
if (roundBits > halfway ) {
absResult += 1 ;
} else if (roundBits == halfway ) {
absResult += absResult & 1 ;
}
} else if (aAbs > srcInfinity ) {
// Conjure the result by beginning with infinity, setting the qNaN
// bit and inserting the (truncated) trailing NaN field.
absResult = @as (dst_rep_t , @intCast (dstInfExp )) << dstSigBits ;
absResult |= dstQNaN ;
absResult |= @intCast (((aAbs & srcNaNCode ) >> (srcSigBits - dstSigBits )) & dstNaNCode );
} else if (aAbs >= overflow ) {
absResult = @as (dst_rep_t , @intCast (dstInfExp )) << dstSigBits ;
} else {
// zero. The result may be a denormal or zero. Extract the exponent
// to get the shift amount for the denormalization.
const aExp : u32 = @intCast (aAbs >> srcSigBits );
const shift : u32 = @intCast (srcExpBias - dstExpBias - aExp + 1 );
const significand : src_rep_t = (aRep & srcSignificandMask ) | srcMinNormal ;
if (shift > srcSigBits ) {
absResult = 0 ;
} else {
const sticky : src_rep_t = @intFromBool (significand << @intCast (srcBits - shift ) != 0 );
const denormalizedSignificand : src_rep_t = significand >> @intCast (shift ) | sticky ;
absResult = @intCast (denormalizedSignificand >> (srcSigBits - dstSigBits ));
const roundBits : src_rep_t = denormalizedSignificand & roundMask ;
if (roundBits > halfway ) {
absResult += 1 ;
} else if (roundBits == halfway ) {
absResult += absResult & 1 ;
}
}
}
const result : dst_rep_t align (@alignOf (dst_t )) = absResult |
@as (dst_rep_t , @truncate (sign >> @intCast (srcBits - dstBits )));
return @bitCast (result );
}