float_utilst::unbiased_floatt float_utilst::unpack(const bvt &src) { assert(src.size()==spec.width()); unbiased_floatt result; result.sign=sign_bit(src); result.fraction=get_fraction(src); result.fraction.push_back(is_normal(src)); // add hidden bit result.exponent=get_exponent(src); assert(result.exponent.size()==spec.e); // unbias the exponent literalt denormal=bv_utils.is_zero(result.exponent); result.exponent= bv_utils.select(denormal, bv_utils.build_constant(-spec.bias()+1, spec.e), sub_bias(result.exponent)); result.infinity=is_infinity(src); result.zero=is_zero(src); result.NaN=is_NaN(src); return result; }
void ieee_floatt::extract_base10( mp_integer &_fraction, mp_integer &_exponent) const { if(is_zero() || is_NaN() || is_infinity()) { _fraction=_exponent=0; return; } _exponent=exponent; _fraction=fraction; // adjust exponent _exponent-=spec.f; // now make it base 10 if(_exponent>=0) { _fraction*=power(2, _exponent); _exponent=0; } else // _exponent<0 { // 10/2=5 -- this makes it base 10 _fraction*=power(5, -_exponent); } // try to re-normalize while((_fraction%10)==0) { _fraction/=10; ++_exponent; } }
bvt float_utilst::mul(const bvt &src1, const bvt &src2) { // unpack const unbiased_floatt unpacked1=unpack(src1); const unbiased_floatt unpacked2=unpack(src2); // zero-extend the fractions const bvt fraction1=bv_utils.zero_extension(unpacked1.fraction, unpacked1.fraction.size()*2); const bvt fraction2=bv_utils.zero_extension(unpacked2.fraction, unpacked2.fraction.size()*2); // multiply fractions unbiased_floatt result; result.fraction=bv_utils.unsigned_multiplier(fraction1, fraction2); // extend exponents to account for overflow // add two bits, as we do extra arithmetic on it later const bvt exponent1=bv_utils.sign_extension(unpacked1.exponent, unpacked1.exponent.size()+2); const bvt exponent2=bv_utils.sign_extension(unpacked2.exponent, unpacked2.exponent.size()+2); bvt added_exponent=bv_utils.add(exponent1, exponent2); // adjust, we are thowing in an extra fraction bit // it has been extended above result.exponent=bv_utils.inc(added_exponent); // new sign result.sign=prop.lxor(unpacked1.sign, unpacked2.sign); // infinity? result.infinity=prop.lor(unpacked1.infinity, unpacked2.infinity); // NaN? { bvt NaN_cond; NaN_cond.push_back(is_NaN(src1)); NaN_cond.push_back(is_NaN(src2)); // infinity * 0 is NaN! NaN_cond.push_back(prop.land(unpacked1.zero, unpacked2.infinity)); NaN_cond.push_back(prop.land(unpacked2.zero, unpacked1.infinity)); result.NaN=prop.lor(NaN_cond); } return rounder(result); }
/// Sets *this to the next representable number closer to plus infinity (greater /// = true) or minus infinity (greater = false). void ieee_floatt::next_representable(bool greater) { if(is_NaN()) return; bool old_sign=get_sign(); if(is_zero()) { unpack(1); set_sign(!greater); return; } if(is_infinity()) { if(get_sign()==greater) { make_fltmax(); set_sign(old_sign); } return; } bool dir; if(greater) dir=!get_sign(); else dir=get_sign(); set_sign(false); mp_integer old=pack(); if(dir) ++old; else --old; unpack(old); // sign change impossible (zero case caught earler) set_sign(old_sign); }
void ieee_floatt::extract_base2( mp_integer &_fraction, mp_integer &_exponent) const { if(is_zero() || is_NaN() || is_infinity()) { _fraction=_exponent=0; return; } _exponent=exponent; _fraction=fraction; // adjust exponent _exponent-=spec.f; // try to integer-ize while((_fraction%2)==0) { _fraction/=2; ++_exponent; } }
literalt float_utilst::relation( const bvt &src1, relt rel, const bvt &src2) { if(rel==GT) return relation(src2, LT, src1); // swapped else if(rel==GE) return relation(src2, LE, src1); // swapped assert(rel==EQ || rel==LT || rel==LE); // special cases: -0 and 0 are equal literalt is_zero1=is_zero(src1); literalt is_zero2=is_zero(src2); literalt both_zero=prop.land(is_zero1, is_zero2); // NaN compares to nothing literalt is_NaN1=is_NaN(src1); literalt is_NaN2=is_NaN(src2); literalt NaN=prop.lor(is_NaN1, is_NaN2); if(rel==LT || rel==LE) { literalt bitwise_equal=bv_utils.equal(src1, src2); // signs different? trivial! Unless Zero. literalt signs_different= prop.lxor(sign_bit(src1), sign_bit(src2)); // as long as the signs match: compare like unsigned numbers // this works due to the BIAS literalt less_than1=bv_utils.unsigned_less_than(src1, src2); // if both are negative (and not the same), need to turn around! literalt less_than2= prop.lxor(less_than1, prop.land(sign_bit(src1), sign_bit(src2))); literalt less_than3= prop.lselect(signs_different, sign_bit(src1), less_than2); if(rel==LT) { bvt and_bv; and_bv.push_back(less_than3); and_bv.push_back(!bitwise_equal); // for the case of two negative numbers and_bv.push_back(!both_zero); and_bv.push_back(!NaN); return prop.land(and_bv); } else if(rel==LE) { bvt or_bv; or_bv.push_back(less_than3); or_bv.push_back(both_zero); or_bv.push_back(bitwise_equal); return prop.land(prop.lor(or_bv), !NaN); } else assert(false); } else if(rel==EQ) { literalt bitwise_equal=bv_utils.equal(src1, src2); return prop.land( prop.lor(bitwise_equal, both_zero), !NaN); } else assert(0); // not reached return const_literal(false); }
void ieee_floatt::next_representable(bool greater) { if(is_NaN()) return; bool old_sign = get_sign(); if(is_zero()) { unpack(1); set_sign(!greater); return; } if(is_infinity()) { if(get_sign() == greater) { make_fltmax(); set_sign(old_sign); } return; } bool dir; if(greater) { if(get_sign()) dir = false; else dir = true; } else { if(get_sign()) dir = true; else dir = false; } set_sign(false); mp_integer old = pack(); if(dir) ++old; else --old; unpack(old); //sign change impossible (zero case caught earler) set_sign(old_sign); //mp_integer new_exp = exponent; //mp_integer new_frac = fraction + dir; //std::cout << exponent << ":" << fraction << std::endl; //std::cout << new_exp << ":" << new_frac << std::endl; //if(get_sign()) // new_frac.negate(); //new_exp -= spec.f; //build(new_frac, new_exp); }