diff --git a/jbmc/src/java_bytecode/assignments_from_json.cpp b/jbmc/src/java_bytecode/assignments_from_json.cpp index d4e3f6e7308..dee711f00e6 100644 --- a/jbmc/src/java_bytecode/assignments_from_json.cpp +++ b/jbmc/src/java_bytecode/assignments_from_json.cpp @@ -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()}); } diff --git a/jbmc/src/java_bytecode/expr2java.cpp b/jbmc/src/java_bytecode/expr2java.cpp index 376b331a573..67d3f33fdd0 100644 --- a/jbmc/src/java_bytecode/expr2java.cpp +++ b/jbmc/src/java_bytecode/expr2java.cpp @@ -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()); diff --git a/jbmc/src/java_bytecode/java_bytecode_convert_method.cpp b/jbmc/src/java_bytecode/java_bytecode_convert_method.cpp index 1bae680fa5d..8d3c23d50f3 100644 --- a/jbmc/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/jbmc/src/java_bytecode/java_bytecode_convert_method.cpp @@ -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(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(); + } } else { diff --git a/jbmc/src/java_bytecode/java_bytecode_parser.cpp b/jbmc/src/java_bytecode/java_bytecode_parser.cpp index ccf9375e717..e036b06bdc4 100644 --- a/jbmc/src/java_bytecode/java_bytecode_parser.cpp +++ b/jbmc/src/java_bytecode/java_bytecode_parser.cpp @@ -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(); } @@ -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(); } diff --git a/jbmc/src/java_bytecode/java_string_library_preprocess.cpp b/jbmc/src/java_bytecode/java_string_library_preprocess.cpp index 7a3f10d403f..18106895546 100644 --- a/jbmc/src/java_bytecode/java_string_library_preprocess.cpp +++ b/jbmc/src/java_bytecode/java_string_library_preprocess.cpp @@ -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(); @@ -996,7 +996,7 @@ 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 = @@ -1004,8 +1004,9 @@ code_blockt java_string_library_preprocesst::make_float_to_string_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); diff --git a/src/analyses/interval_domain.cpp b/src/analyses/interval_domain.cpp index 4594a4d2e94..ed1fb8acd1f 100644 --- a/src/analyses/interval_domain.cpp +++ b/src/analyses/interval_domain.cpp @@ -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)); if(id==ID_lt) tmp.decrement(); ieee_float_intervalt &fi=float_map[lhs_identifier]; @@ -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)); if(id==ID_lt) tmp.increment(); ieee_float_intervalt &fi=float_map[rhs_identifier]; diff --git a/src/analyses/interval_domain.h b/src/analyses/interval_domain.h index e6a21f76d18..31638097c4a 100644 --- a/src/analyses/interval_domain.h +++ b/src/analyses/interval_domain.h @@ -18,7 +18,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "ai_domain.h" -typedef interval_templatet ieee_float_intervalt; +typedef interval_templatet ieee_float_intervalt; class interval_domaint:public ai_domain_baset { diff --git a/src/ansi-c/expr2c.cpp b/src/ansi-c/expr2c.cpp index 07003ead306..6a390a2100f 100644 --- a/src/ansi-c/expr2c.cpp +++ b/src/ansi-c/expr2c.cpp @@ -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])) { diff --git a/src/ansi-c/goto-conversion/goto_check_c.cpp b/src/ansi-c/goto-conversion/goto_check_c.cpp index aadac285968..6ff092e2555 100644 --- a/src/ansi-c/goto-conversion/goto_check_c.cpp +++ b/src/ansi-c/goto-conversion/goto_check_c.cpp @@ -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); 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); lower.from_integer(-power(2, new_width - 1) - 1); const binary_relation_exprt no_overflow_lower( op, ID_gt, lower.to_expr()); @@ -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); 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); lower.from_integer(-1); const binary_relation_exprt no_overflow_lower( op, ID_gt, lower.to_expr()); @@ -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( @@ -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( diff --git a/src/ansi-c/literals/convert_float_literal.cpp b/src/ansi-c/literals/convert_float_literal.cpp index 283a852c074..46040693dbe 100644 --- a/src/ansi-c/literals/convert_float_literal.cpp +++ b/src/ansi-c/literals/convert_float_literal.cpp @@ -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. + 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); diff --git a/src/goto-instrument/goto_program2code.cpp b/src/goto-instrument/goto_program2code.cpp index 6f18202d305..87edc71b678 100644 --- a/src/goto-instrument/goto_program2code.cpp +++ b/src/goto-instrument/goto_program2code.cpp @@ -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"); } diff --git a/src/goto-programs/interpreter.cpp b/src/goto-programs/interpreter.cpp index 3104f1d9de8..8ad54ddbf2d 100644 --- a/src/goto-programs/interpreter.cpp +++ b/src/goto-programs/interpreter.cpp @@ -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)); f.unpack(rhs[numeric_cast_v(offset)]); return f.to_expr(); } diff --git a/src/goto-programs/interpreter_evaluate.cpp b/src/goto-programs/interpreter_evaluate.cpp index 3cda7db79d0..72707e3692f 100644 --- a/src/goto-programs/interpreter_evaluate.cpp +++ b/src/goto-programs/interpreter_evaluate.cpp @@ -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; f.from_expr(to_constant_expr(expr)); return {f.pack()}; } @@ -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); f1.unpack(result); f2.unpack(tmp.front()); f1*=f2; diff --git a/src/goto-programs/json_expr.cpp b/src/goto-programs/json_expr.cpp index 16139131b90..6331ebe2f6a 100644 --- a/src/goto-programs/json_expr.cpp +++ b/src/goto-programs/json_expr.cpp @@ -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) { diff --git a/src/goto-programs/xml_expr.cpp b/src/goto-programs/xml_expr.cpp index a07ce2cbe21..2cf54e5261f 100644 --- a/src/goto-programs/xml_expr.cpp +++ b/src/goto-programs/xml_expr.cpp @@ -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) { diff --git a/src/solvers/floatbv/float_bv.cpp b/src/solvers/floatbv/float_bv.cpp index 162f1e8cd0a..9450694fb43 100644 --- a/src/solvers/floatbv/float_bv.cpp +++ b/src/solvers/floatbv/float_bv.cpp @@ -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()); diff --git a/src/solvers/floatbv/float_utils.cpp b/src/solvers/floatbv/float_utils.cpp index 13706f06bd5..dc94a842226 100644 --- a/src/solvers/floatbv/float_utils.cpp +++ b/src/solvers/floatbv/float_utils.cpp @@ -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; @@ -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