@@ -6,16 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com
66
77\*******************************************************************/
88
9- #include " boolbv.h"
10-
11- #include < algorithm>
12-
139#include < util/bitvector_types.h>
1410#include < util/c_types.h>
1511#include < util/floatbv_expr.h>
1612
1713#include < solvers/floatbv/float_utils.h>
1814
15+ #include " boolbv.h"
16+
1917bvt boolbvt::convert_floatbv_typecast (const floatbv_typecast_exprt &expr)
2018{
2119 const exprt &op0=expr.op (); // number to convert
@@ -131,44 +129,66 @@ bvt boolbvt::convert_floatbv_op(const ieee_float_op_exprt &expr)
131129 sub_width > 0 && width % sub_width == 0 ,
132130 " width of a complex subtype must be positive and evenly divide the "
133131 " width of the complex expression" );
132+ DATA_INVARIANT (
133+ sub_width * 2 == width, " a complex type consists of exactly two parts" );
134134
135- std::size_t size=width/sub_width;
136- bvt result_bv;
137- result_bv.resize (width);
135+ bvt lhs_real{lhs_as_bv.begin (), lhs_as_bv.begin () + sub_width};
136+ bvt rhs_real{rhs_as_bv.begin (), rhs_as_bv.begin () + sub_width};
138137
139- for (std::size_t i=0 ; i<size; i++)
138+ bvt lhs_imag{lhs_as_bv.begin () + sub_width, lhs_as_bv.end ()};
139+ bvt rhs_imag{rhs_as_bv.begin () + sub_width, rhs_as_bv.end ()};
140+
141+ bvt result_real, result_imag;
142+
143+ if (expr.id () == ID_floatbv_plus || expr.id () == ID_floatbv_minus)
144+ {
145+ result_real = float_utils.add_sub (
146+ lhs_real, rhs_real, expr.id () == ID_floatbv_minus);
147+ result_imag = float_utils.add_sub (
148+ lhs_imag, rhs_imag, expr.id () == ID_floatbv_minus);
149+ }
150+ else if (expr.id () == ID_floatbv_mult)
151+ {
152+ // Could be optimised to just three multiplications with more additions
153+ // instead, but then we'd have to worry about the impact of possible
154+ // overflows. So we use the naive approach for now:
155+ result_real = float_utils.add_sub (
156+ float_utils.mul (lhs_real, rhs_real),
157+ float_utils.mul (lhs_imag, rhs_imag),
158+ true );
159+ result_imag = float_utils.add_sub (
160+ float_utils.mul (lhs_real, rhs_imag),
161+ float_utils.mul (lhs_imag, rhs_real),
162+ false );
163+ }
164+ else if (expr.id () == ID_floatbv_div)
140165 {
141- bvt lhs_sub_bv, rhs_sub_bv, sub_result_bv;
142-
143- lhs_sub_bv.assign (
144- lhs_as_bv.begin () + i * sub_width,
145- lhs_as_bv.begin () + (i + 1 ) * sub_width);
146- rhs_sub_bv.assign (
147- rhs_as_bv.begin () + i * sub_width,
148- rhs_as_bv.begin () + (i + 1 ) * sub_width);
149-
150- if (expr.id ()==ID_floatbv_plus)
151- sub_result_bv = float_utils.add_sub (lhs_sub_bv, rhs_sub_bv, false );
152- else if (expr.id ()==ID_floatbv_minus)
153- sub_result_bv = float_utils.add_sub (lhs_sub_bv, rhs_sub_bv, true );
154- else if (expr.id ()==ID_floatbv_mult)
155- sub_result_bv = float_utils.mul (lhs_sub_bv, rhs_sub_bv);
156- else if (expr.id ()==ID_floatbv_div)
157- sub_result_bv = float_utils.div (lhs_sub_bv, rhs_sub_bv);
158- else
159- UNREACHABLE;
160-
161- INVARIANT (
162- sub_result_bv.size () == sub_width,
163- " we constructed a new complex of the right size" );
164- INVARIANT (
165- i * sub_width + sub_width - 1 < result_bv.size (),
166- " the sub-bitvector fits into the result bitvector" );
167- std::copy (
168- sub_result_bv.begin (),
169- sub_result_bv.end (),
170- result_bv.begin () + i * sub_width);
166+ bvt numerator_real = float_utils.add_sub (
167+ float_utils.mul (lhs_real, rhs_real),
168+ float_utils.mul (lhs_imag, rhs_imag),
169+ false );
170+ bvt numerator_imag = float_utils.add_sub (
171+ float_utils.mul (lhs_imag, rhs_real),
172+ float_utils.mul (lhs_real, rhs_imag),
173+ true );
174+
175+ bvt denominator = float_utils.add_sub (
176+ float_utils.mul (rhs_real, rhs_real),
177+ float_utils.mul (rhs_imag, rhs_imag),
178+ false );
179+
180+ result_real = float_utils.div (numerator_real, denominator);
181+ result_imag = float_utils.div (numerator_imag, denominator);
171182 }
183+ else
184+ UNREACHABLE;
185+
186+ bvt result_bv = std::move (result_real);
187+ result_bv.reserve (width);
188+ result_bv.insert (
189+ result_bv.end (),
190+ std::make_move_iterator (result_imag.begin ()),
191+ std::make_move_iterator (result_imag.end ()));
172192
173193 return result_bv;
174194 }
0 commit comments