Skip to content

Commit

Permalink
Split ieee_floatt into ieee_float_valuet and ieee_floatt
Browse files Browse the repository at this point in the history
This splits ieee_floatt into two parts:

1) ieee_float_valuet stores an IEEE 754 floating-point value.  It offers no
operations that require rounding, and hence, does not require a rounding
mode.

2) ieee_floatt extends ieee_float_valuet with a rounding mode, and hence,
offers operators that require rounding.
  • Loading branch information
kroening committed Jan 9, 2025
1 parent 36b2335 commit 5c8766d
Show file tree
Hide file tree
Showing 33 changed files with 520 additions and 473 deletions.
4 changes: 2 additions & 2 deletions jbmc/src/java_bytecode/assignments_from_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,13 +358,13 @@ assign_primitive_from_json(const exprt &expr, const jsont &json)
}
else if(expr.type() == java_double_type())
{
ieee_floatt ieee_float(to_floatbv_type(expr.type()));
ieee_float_valuet ieee_float(to_floatbv_type(expr.type()));
ieee_float.from_double(std::stod(json.value));
result.add(code_frontend_assignt{expr, ieee_float.to_expr()});
}
else if(expr.type() == java_float_type())
{
ieee_floatt ieee_float(to_floatbv_type(expr.type()));
ieee_float_valuet ieee_float(to_floatbv_type(expr.type()));
ieee_float.from_float(std::stof(json.value));
result.add(code_frontend_assignt{expr, ieee_float.to_expr()});
}
Expand Down
2 changes: 1 addition & 1 deletion jbmc/src/java_bytecode/expr2java.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ std::string expr2javat::convert_constant(
(src.type()==java_double_type()))
{
// This converts NaNs to the canonical NaN
const ieee_floatt ieee_repr(to_constant_expr(src));
const ieee_float_valuet ieee_repr(to_constant_expr(src));
if(ieee_repr.is_double())
return floating_point_to_java_string(ieee_repr.to_double());
return floating_point_to_java_string(ieee_repr.to_float());
Expand Down
11 changes: 7 additions & 4 deletions jbmc/src/java_bytecode/java_bytecode_convert_method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2181,16 +2181,19 @@ exprt::operandst &java_bytecode_convert_methodt::convert_const(
is_float ? ieee_float_spect::single_precision()
: ieee_float_spect::double_precision());

ieee_floatt value(spec);
if(arg0.type().id() != ID_floatbv)
{
// conversion from integer to float may need rounding
auto rm = ieee_floatt::rounding_modet::ROUND_TO_EVEN;
const mp_integer number = numeric_cast_v<mp_integer>(arg0);
ieee_floatt value(spec, rm);
value.from_integer(number);
results[0] = value.to_expr();
}
else
value.from_expr(arg0);

results[0] = value.to_expr();
{
results[0] = ieee_float_valuet{arg0}.to_expr();

Check warning on line 2195 in jbmc/src/java_bytecode/java_bytecode_convert_method.cpp

View check run for this annotation

Codecov / codecov/patch

jbmc/src/java_bytecode/java_bytecode_convert_method.cpp#L2195

Added line #L2195 was not covered by tests
}
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions jbmc/src/java_bytecode/java_bytecode_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ void java_bytecode_parsert::rconstant_pool()

case CONSTANT_Float:
{
ieee_floatt value(ieee_float_spect::single_precision());
ieee_float_valuet value(ieee_float_spect::single_precision());
value.unpack(entry.number);
entry.expr = value.to_expr();
}
Expand All @@ -794,7 +794,7 @@ void java_bytecode_parsert::rconstant_pool()

case CONSTANT_Double:
{
ieee_floatt value(ieee_float_spect::double_precision());
ieee_float_valuet value(ieee_float_spect::double_precision());
value.unpack(entry.number);
entry.expr = value.to_expr();
}
Expand Down
9 changes: 5 additions & 4 deletions jbmc/src/java_bytecode/java_string_library_preprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ code_blockt java_string_library_preprocesst::make_float_to_string_code(

// Expression representing 0.0
const ieee_float_spect float_spec{to_floatbv_type(params[0].type())};
ieee_floatt zero_float(float_spec);
ieee_float_valuet zero_float(float_spec);
zero_float.from_float(0.0);
const constant_exprt zero = zero_float.to_expr();

Expand Down Expand Up @@ -996,16 +996,17 @@ code_blockt java_string_library_preprocesst::make_float_to_string_code(
string_expr_list.push_back(zero_string);

// Case of -0.0
ieee_floatt minus_zero_float(float_spec);
ieee_float_valuet minus_zero_float(float_spec);
minus_zero_float.from_float(-0.0f);
condition_list.push_back(equal_exprt(arg, minus_zero_float.to_expr()));
const refined_string_exprt minus_zero_string =
string_literal_to_string_expr("-0.0", loc, symbol_table, code);
string_expr_list.push_back(minus_zero_string);

// Case of simple notation
ieee_floatt bound_inf_float(float_spec);
ieee_floatt bound_sup_float(float_spec);
auto rm = ieee_floatt::rounding_modet::ROUND_TO_EVEN;
ieee_floatt bound_inf_float(float_spec, rm);
ieee_floatt bound_sup_float(float_spec, rm);
bound_inf_float.from_float(1e-3f);
bound_sup_float.from_float(1e7f);
bound_inf_float.change_spec(float_spec);
Expand Down
4 changes: 2 additions & 2 deletions src/analyses/interval_domain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ void interval_domaint::assume_rec(
}
else if(is_float(lhs.type()) && is_float(rhs.type()))
{
ieee_floatt tmp(to_constant_expr(rhs));
ieee_float_valuet tmp(to_constant_expr(rhs));

Check warning on line 291 in src/analyses/interval_domain.cpp

View check run for this annotation

Codecov / codecov/patch

src/analyses/interval_domain.cpp#L291

Added line #L291 was not covered by tests
if(id==ID_lt)
tmp.decrement();
ieee_float_intervalt &fi=float_map[lhs_identifier];
Expand All @@ -313,7 +313,7 @@ void interval_domaint::assume_rec(
}
else if(is_float(lhs.type()) && is_float(rhs.type()))
{
ieee_floatt tmp(to_constant_expr(lhs));
ieee_float_valuet tmp(to_constant_expr(lhs));

Check warning on line 316 in src/analyses/interval_domain.cpp

View check run for this annotation

Codecov / codecov/patch

src/analyses/interval_domain.cpp#L316

Added line #L316 was not covered by tests
if(id==ID_lt)
tmp.increment();
ieee_float_intervalt &fi=float_map[rhs_identifier];
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/interval_domain.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Author: Daniel Kroening, [email protected]

#include "ai_domain.h"

typedef interval_templatet<ieee_floatt> ieee_float_intervalt;
typedef interval_templatet<ieee_float_valuet> ieee_float_intervalt;

class interval_domaint:public ai_domain_baset
{
Expand Down
2 changes: 1 addition & 1 deletion src/ansi-c/expr2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1912,7 +1912,7 @@ std::string expr2ct::convert_constant(
}
else if(type.id()==ID_floatbv)
{
dest=ieee_floatt(to_constant_expr(src)).to_ansi_c_string();
dest = ieee_float_valuet(to_constant_expr(src)).to_ansi_c_string();

if(!dest.empty() && isdigit(dest[dest.size() - 1]))
{
Expand Down
18 changes: 10 additions & 8 deletions src/ansi-c/goto-conversion/goto_check_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,12 +761,13 @@ void goto_check_ct::conversion_check(const exprt &expr, const guardt &guard)
else if(old_type.id() == ID_floatbv) // float -> signed
{
// Note that the fractional part is truncated!
ieee_floatt upper(to_floatbv_type(old_type));
auto rm = ieee_floatt::rounding_modet::ROUND_TO_EVEN;
ieee_floatt upper(to_floatbv_type(old_type), rm);

Check warning on line 765 in src/ansi-c/goto-conversion/goto_check_c.cpp

View check run for this annotation

Codecov / codecov/patch

src/ansi-c/goto-conversion/goto_check_c.cpp#L764-L765

Added lines #L764 - L765 were not covered by tests
upper.from_integer(power(2, new_width - 1));
const binary_relation_exprt no_overflow_upper(
op, ID_lt, upper.to_expr());

ieee_floatt lower(to_floatbv_type(old_type));
ieee_floatt lower(to_floatbv_type(old_type), rm);

Check warning on line 770 in src/ansi-c/goto-conversion/goto_check_c.cpp

View check run for this annotation

Codecov / codecov/patch

src/ansi-c/goto-conversion/goto_check_c.cpp#L770

Added line #L770 was not covered by tests
lower.from_integer(-power(2, new_width - 1) - 1);
const binary_relation_exprt no_overflow_lower(
op, ID_gt, lower.to_expr());
Expand Down Expand Up @@ -844,12 +845,13 @@ void goto_check_ct::conversion_check(const exprt &expr, const guardt &guard)
else if(old_type.id() == ID_floatbv) // float -> unsigned
{
// Note that the fractional part is truncated!
ieee_floatt upper(to_floatbv_type(old_type));
auto rm = ieee_floatt::rounding_modet::ROUND_TO_EVEN;
ieee_floatt upper(to_floatbv_type(old_type), rm);

Check warning on line 849 in src/ansi-c/goto-conversion/goto_check_c.cpp

View check run for this annotation

Codecov / codecov/patch

src/ansi-c/goto-conversion/goto_check_c.cpp#L848-L849

Added lines #L848 - L849 were not covered by tests
upper.from_integer(power(2, new_width));
const binary_relation_exprt no_overflow_upper(
op, ID_lt, upper.to_expr());

ieee_floatt lower(to_floatbv_type(old_type));
ieee_floatt lower(to_floatbv_type(old_type), rm);

Check warning on line 854 in src/ansi-c/goto-conversion/goto_check_c.cpp

View check run for this annotation

Codecov / codecov/patch

src/ansi-c/goto-conversion/goto_check_c.cpp#L854

Added line #L854 was not covered by tests
lower.from_integer(-1);
const binary_relation_exprt no_overflow_lower(
op, ID_gt, lower.to_expr());
Expand Down Expand Up @@ -1295,8 +1297,8 @@ void goto_check_ct::nan_check(const exprt &expr, const guardt &guard)
// -inf + +inf = NaN and +inf + -inf = NaN,
// i.e., signs differ
ieee_float_spect spec = ieee_float_spect(to_floatbv_type(plus_expr.type()));
exprt plus_inf = ieee_floatt::plus_infinity(spec).to_expr();
exprt minus_inf = ieee_floatt::minus_infinity(spec).to_expr();
exprt plus_inf = ieee_float_valuet::plus_infinity(spec).to_expr();
exprt minus_inf = ieee_float_valuet::minus_infinity(spec).to_expr();

isnan = or_exprt(
and_exprt(
Expand All @@ -1315,8 +1317,8 @@ void goto_check_ct::nan_check(const exprt &expr, const guardt &guard)

ieee_float_spect spec =
ieee_float_spect(to_floatbv_type(minus_expr.type()));
exprt plus_inf = ieee_floatt::plus_infinity(spec).to_expr();
exprt minus_inf = ieee_floatt::minus_infinity(spec).to_expr();
exprt plus_inf = ieee_float_valuet::plus_infinity(spec).to_expr();
exprt minus_inf = ieee_float_valuet::minus_infinity(spec).to_expr();

isnan = or_exprt(
and_exprt(
Expand Down
4 changes: 3 additions & 1 deletion src/ansi-c/literals/convert_float_literal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ exprt convert_float_literal(const std::string &src)
// but these aren't handled anywhere
}

ieee_floatt a(type);
// This may require rounding.

Check warning on line 74 in src/ansi-c/literals/convert_float_literal.cpp

View check run for this annotation

Codecov / codecov/patch

src/ansi-c/literals/convert_float_literal.cpp#L74

Added line #L74 was not covered by tests
auto rm = ieee_floatt::rounding_modet::ROUND_TO_EVEN;
ieee_floatt a(type, rm);

if(parsed_float.exponent_base==10)
a.from_base10(parsed_float.significand, parsed_float.exponent);
Expand Down
2 changes: 1 addition & 1 deletion src/goto-instrument/goto_program2code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1923,7 +1923,7 @@ void goto_program2codet::cleanup_expr(exprt &expr, bool no_typecast)
{
if(expr.type().id()==ID_floatbv)
{
const ieee_floatt f(to_constant_expr(expr));
const ieee_float_valuet f(to_constant_expr(expr));
if(f.is_NaN() || f.is_infinity())
system_headers.insert("math.h");
}
Expand Down
2 changes: 1 addition & 1 deletion src/goto-programs/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ exprt interpretert::get_value(
}
else if(type.id() == ID_floatbv)
{
ieee_floatt f(to_floatbv_type(type));
ieee_float_valuet f(to_floatbv_type(type));

Check warning on line 579 in src/goto-programs/interpreter.cpp

View check run for this annotation

Codecov / codecov/patch

src/goto-programs/interpreter.cpp#L579

Added line #L579 was not covered by tests
f.unpack(rhs[numeric_cast_v<std::size_t>(offset)]);
return f.to_expr();
}
Expand Down
7 changes: 4 additions & 3 deletions src/goto-programs/interpreter_evaluate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ interpretert::mp_vectort interpretert::evaluate(const exprt &expr)
}
else if(expr.type().id()==ID_floatbv)
{
ieee_floatt f;
ieee_float_valuet f;

Check warning on line 367 in src/goto-programs/interpreter_evaluate.cpp

View check run for this annotation

Codecov / codecov/patch

src/goto-programs/interpreter_evaluate.cpp#L367

Added line #L367 was not covered by tests
f.from_expr(to_constant_expr(expr));
return {f.pack()};
}
Expand Down Expand Up @@ -731,8 +731,9 @@ interpretert::mp_vectort interpretert::evaluate(const exprt &expr)
}
else if(expr.type().id()==ID_floatbv)
{
ieee_floatt f1(to_floatbv_type(expr.type()));
ieee_floatt f2(to_floatbv_type(op.type()));
auto rm = ieee_floatt::rounding_modet::ROUND_TO_EVEN;
ieee_floatt f1(to_floatbv_type(expr.type()), rm);
ieee_floatt f2(to_floatbv_type(op.type()), rm);

Check warning on line 736 in src/goto-programs/interpreter_evaluate.cpp

View check run for this annotation

Codecov / codecov/patch

src/goto-programs/interpreter_evaluate.cpp#L734-L736

Added lines #L734 - L736 were not covered by tests
f1.unpack(result);
f2.unpack(tmp.front());
f1*=f2;
Expand Down
2 changes: 1 addition & 1 deletion src/goto-programs/json_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ json_objectt json(const exprt &expr, const namespacet &ns, const irep_idt &mode)
json_numbert(std::to_string(to_bitvector_type(type).get_width()));
result["binary"] = json_stringt(binary(constant_expr));
result["data"] =
json_stringt(ieee_floatt(constant_expr).to_ansi_c_string());
json_stringt(ieee_float_valuet(constant_expr).to_ansi_c_string());
}
else if(type.id() == ID_pointer)
{
Expand Down
2 changes: 1 addition & 1 deletion src/goto-programs/xml_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ xmlt xml(const exprt &expr, const namespacet &ns)
result.set_attribute("width", width);
result.set_attribute(
"binary", integer2binary(bvrep2integer(value, width, false), width));
result.data = ieee_floatt(constant_expr).to_ansi_c_string();
result.data = ieee_float_valuet(constant_expr).to_ansi_c_string();
}
else if(type.id() == ID_pointer)
{
Expand Down
2 changes: 1 addition & 1 deletion src/solvers/floatbv/float_bv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ exprt float_bvt::is_zero(const exprt &src)

constant_exprt mask(integer2bvrep(v, width), src.type());

ieee_floatt z(type);
ieee_float_valuet z(type);
z.make_zero();

return equal_exprt(bitand_exprt(src, mask), z.to_expr());
Expand Down
6 changes: 3 additions & 3 deletions src/solvers/floatbv/float_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bvt float_utilst::to_integer(
return result;
}

bvt float_utilst::build_constant(const ieee_floatt &src)
bvt float_utilst::build_constant(const ieee_float_valuet &src)
{
unbiased_floatt result;

Expand Down Expand Up @@ -1268,14 +1268,14 @@ bvt float_utilst::pack(const biased_floatt &src)
return result;
}

ieee_floatt float_utilst::get(const bvt &src) const
ieee_float_valuet float_utilst::get(const bvt &src) const
{
mp_integer int_value=0;

for(std::size_t i=0; i<src.size(); i++)
int_value+=power(2, i)*prop.l_get(src[i]).is_true();

ieee_floatt result;
ieee_float_valuet result;
result.spec=spec;
result.unpack(int_value);

Expand Down
4 changes: 2 additions & 2 deletions src/solvers/floatbv/float_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class float_utilst

ieee_float_spect spec;

bvt build_constant(const ieee_floatt &);
bvt build_constant(const ieee_float_valuet &);

static inline literalt sign_bit(const bvt &src)
{
Expand Down Expand Up @@ -139,7 +139,7 @@ class float_utilst
literalt relation(const bvt &src1, relt rel, const bvt &src2);

// constants
ieee_floatt get(const bvt &) const;
ieee_float_valuet get(const bvt &) const;

// helpers
literalt exponent_all_ones(const bvt &);
Expand Down
10 changes: 6 additions & 4 deletions src/solvers/smt2/smt2_conv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,23 +476,25 @@ constant_exprt smt2_convt::parse_literal(
{
std::size_t e = unsafe_string2size_t(src.get_sub()[2].id_string());
std::size_t s = unsafe_string2size_t(src.get_sub()[3].id_string());
return ieee_floatt::plus_infinity(ieee_float_spect(s - 1, e)).to_expr();
return ieee_float_valuet::plus_infinity(ieee_float_spect(s - 1, e))
.to_expr();
}
else if(src.get_sub().size()==4 &&
src.get_sub()[0].id()=="_" &&
src.get_sub()[1].id()=="-oo") // (_ -oo e s)
{
std::size_t e = unsafe_string2size_t(src.get_sub()[2].id_string());
std::size_t s = unsafe_string2size_t(src.get_sub()[3].id_string());
return ieee_floatt::minus_infinity(ieee_float_spect(s - 1, e)).to_expr();
return ieee_float_valuet::minus_infinity(ieee_float_spect(s - 1, e))
.to_expr();
}
else if(src.get_sub().size()==4 &&
src.get_sub()[0].id()=="_" &&
src.get_sub()[1].id()=="NaN") // (_ NaN e s)
{
std::size_t e = unsafe_string2size_t(src.get_sub()[2].id_string());
std::size_t s = unsafe_string2size_t(src.get_sub()[3].id_string());
return ieee_floatt::NaN(ieee_float_spect(s - 1, e)).to_expr();
return ieee_float_valuet::NaN(ieee_float_spect(s - 1, e)).to_expr();
}

if(type.id()==ID_signedbv ||
Expand Down Expand Up @@ -3445,7 +3447,7 @@ void smt2_convt::convert_constant(const constant_exprt &expr)
significands including the hidden bit. Thus some encoding
is needed to get to IEEE-754 style representations. */

ieee_floatt v=ieee_floatt(expr);
ieee_float_valuet v = ieee_float_valuet(expr);
size_t e=floatbv_type.get_e();
size_t f=floatbv_type.get_f()+1;

Expand Down
2 changes: 1 addition & 1 deletion src/solvers/smt2/smt2_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ std::ostream &smt2_format_rec(std::ostream &out, const exprt &expr)
}
else if(expr_type.id() == ID_floatbv)
{
const ieee_floatt v = ieee_floatt(constant_expr);
const ieee_float_valuet v = ieee_float_valuet(constant_expr);
const size_t e = v.spec.e;
const size_t f = v.spec.f + 1; // SMT-LIB counts the hidden bit

Expand Down
2 changes: 1 addition & 1 deletion src/solvers/strings/string_constraint_generator_float.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ exprt get_significand(
/// \return an expression representing this floating point
exprt constant_float(const double f, const ieee_float_spect &float_spec)
{
ieee_floatt fl(float_spec);
ieee_float_valuet fl(float_spec);
if(float_spec == ieee_float_spect::single_precision())
fl.from_float(f);
else if(float_spec == ieee_float_spect::double_precision())
Expand Down
2 changes: 1 addition & 1 deletion src/statement-list/converters/convert_real_literal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Author: Matthias Weiss, [email protected]

constant_exprt convert_real_literal(const std::string &src)
{
ieee_floatt real{get_real_type()};
ieee_float_valuet real{get_real_type()};
real.from_float(std::stof(src));
return real.to_expr();
}
2 changes: 1 addition & 1 deletion src/statement-list/statement_list_parse_tree_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static void output_constant(std::ostream &os, const constant_exprt &constant)
os << ivalue;
else if(can_cast_type<floatbv_typet>(constant.type()))
{
ieee_floatt real{get_real_type()};
ieee_float_valuet real{get_real_type()};
real.from_expr(constant);
os << real.to_float();
}
Expand Down
4 changes: 3 additions & 1 deletion src/util/arith_tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ constant_exprt from_integer(
}
else if(type_id==ID_floatbv)
{
ieee_floatt ieee_float(to_floatbv_type(type));
ieee_floatt ieee_float(
to_floatbv_type(type), ieee_floatt::rounding_modet::ROUND_TO_EVEN);
// always rounds to zero
ieee_float.from_integer(int_value);
return ieee_float.to_expr();
}
Expand Down
Loading

0 comments on commit 5c8766d

Please sign in to comment.