Function setFloat [src]
Sets the Mutable to a float value rounded according to round.
Returns whether the conversion was exact (round had no effect on the result).
Prototype
pub fn setFloat(self: *Mutable, value: anytype, round: Round) Exactness
Parameters
self: *Mutable
round: Round
Source
pub fn setFloat(self: *Mutable, value: anytype, round: Round) Exactness {
const Float = @TypeOf(value);
if (Float == comptime_float) return self.setFloat(@as(f128, value), round);
const abs_value = @abs(value);
if (abs_value < 1.0) {
if (abs_value == 0.0) {
self.set(0);
return .exact;
}
self.set(@as(i2, round: switch (round) {
.nearest_even => if (abs_value <= 0.5) 0 else continue :round .away,
.away => if (value < 0.0) -1 else 1,
.trunc => 0,
.floor => -@as(i2, @intFromBool(value < 0.0)),
.ceil => @intFromBool(value > 0.0),
}));
return .inexact;
}
const Repr = std.math.FloatRepr(Float);
const repr: Repr = @bitCast(value);
const exponent = repr.exponent.unbias();
assert(exponent >= 0);
const int_bit: Repr.Mantissa = 1 << (@bitSizeOf(Repr.Mantissa) - 1);
const mantissa = int_bit | repr.mantissa;
if (exponent >= @bitSizeOf(Repr.Normalized.Fraction)) {
self.set(mantissa);
self.shiftLeft(self.toConst(), @intCast(exponent - @bitSizeOf(Repr.Normalized.Fraction)));
self.positive = repr.sign == .positive;
return .exact;
}
self.set(mantissa >> @intCast(@bitSizeOf(Repr.Normalized.Fraction) - exponent));
const round_bits: Repr.Normalized.Fraction = @truncate(mantissa << @intCast(exponent));
if (round_bits == 0) {
self.positive = repr.sign == .positive;
return .exact;
}
round: switch (round) {
.nearest_even => {
const half: Repr.Normalized.Fraction = 1 << (@bitSizeOf(Repr.Normalized.Fraction) - 1);
if (round_bits >= half) self.addScalar(self.toConst(), 1);
if (round_bits == half) self.limbs[0] &= ~@as(Limb, 1);
},
.away => self.addScalar(self.toConst(), 1),
.trunc => {},
.floor => switch (repr.sign) {
.positive => {},
.negative => continue :round .away,
},
.ceil => switch (repr.sign) {
.positive => continue :round .away,
.negative => {},
},
}
self.positive = repr.sign == .positive;
return .inexact;
}