CBMC
Loading...
Searching...
No Matches
float_utils.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#include "float_utils.h"
10
11#include <algorithm>
12
13#include <util/arith_tools.h>
14
16{
17 bvt round_to_even=
18 bv_utils.build_constant(ieee_floatt::ROUND_TO_EVEN, src.size());
19 bvt round_to_plus_inf=
20 bv_utils.build_constant(ieee_floatt::ROUND_TO_PLUS_INF, src.size());
21 bvt round_to_minus_inf=
22 bv_utils.build_constant(ieee_floatt::ROUND_TO_MINUS_INF, src.size());
23 bvt round_to_zero=
24 bv_utils.build_constant(ieee_floatt::ROUND_TO_ZERO, src.size());
25 bvt round_to_away =
26 bv_utils.build_constant(ieee_floatt::ROUND_TO_AWAY, src.size());
27
28 rounding_mode_bits.round_to_even=bv_utils.equal(src, round_to_even);
29 rounding_mode_bits.round_to_plus_inf=bv_utils.equal(src, round_to_plus_inf);
30 rounding_mode_bits.round_to_minus_inf=bv_utils.equal(src, round_to_minus_inf);
31 rounding_mode_bits.round_to_zero=bv_utils.equal(src, round_to_zero);
32 rounding_mode_bits.round_to_away = bv_utils.equal(src, round_to_away);
33}
34
36{
37 unbiased_floatt result;
38
39 // we need to convert negative integers
40 result.sign=sign_bit(src);
41
42 result.fraction=bv_utils.absolute_value(src);
43
44 // build an exponent (unbiased) -- this is signed!
45 result.exponent=
46 bv_utils.build_constant(
47 src.size()-1,
48 address_bits(src.size() - 1) + 1);
49
50 return round_and_pack(result);
51}
52
54{
55 unbiased_floatt result;
56
57 result.fraction=src;
58
59 // build an exponent (unbiased) -- this is signed!
60 result.exponent=
61 bv_utils.build_constant(
62 src.size()-1,
63 address_bits(src.size() - 1) + 1);
64
65 result.sign=const_literal(false);
66
67 return round_and_pack(result);
68}
69
71 const bvt &src,
72 std::size_t dest_width)
73{
74 return to_integer(src, dest_width, true);
75}
76
78 const bvt &src,
79 std::size_t dest_width)
80{
81 return to_integer(src, dest_width, false);
82}
83
85 const bvt &src,
86 std::size_t dest_width,
87 bool is_signed)
88{
89 PRECONDITION(src.size() == spec.width());
90
91 // The following is the usual case in ANSI-C, and we optimize for that.
92 PRECONDITION(rounding_mode_bits.round_to_zero.is_true());
93
94 // Keep in sync with float_bvt::to_integer — the body below is a
95 // line-for-line translation of that function between the
96 // literalt/bvt and exprt APIs.
97
98 const unbiased_floatt unpacked = unpack(src);
99
100 bvt fraction = unpacked.fraction;
101
102 if(dest_width > fraction.size())
103 {
104 bvt lsb_extension =
105 bv_utils.build_constant(0U, dest_width - fraction.size());
106 fraction.insert(
107 fraction.begin(), lsb_extension.begin(), lsb_extension.end());
108 }
109
110 // if the exponent is positive, shift right by (fraction.size() - 1) minus
111 // the exponent. The shift distance is built in a bit-vector wide enough to
112 // hold both `fraction.size() - 1` and the (sign-extended) exponent, so it
113 // does not wrap for wide destination types -- e.g. a narrow source such as
114 // _Float16 (spec.e = 5) converted to a 64-bit integer. Keep in sync with
115 // float_bvt::to_integer.
116 const std::size_t distance_width =
117 std::max(unpacked.exponent.size(), address_bits(fraction.size()) + 1);
118 bvt offset = bv_utils.build_constant(fraction.size() - 1, distance_width);
119 bvt distance = bv_utils.sub(
120 offset, bv_utils.sign_extension(unpacked.exponent, distance_width));
121 bvt shift_result =
122 bv_utils.shift(fraction, bv_utilst::shiftt::SHIFT_LRIGHT, distance);
123
124 // if the exponent is negative, we have zero anyways
125 bvt result = shift_result;
126 literalt exponent_sign = unpacked.exponent[unpacked.exponent.size() - 1];
127
128 for(std::size_t i = 0; i < result.size(); i++)
129 result[i] = prop.land(result[i], !exponent_sign);
130
131 // chop out the right number of bits from the result
132 if(result.size() > dest_width)
133 {
134 result.resize(dest_width);
135 }
136
137 INVARIANT(
138 result.size() == dest_width,
139 "result bitvector width should equal the destination bitvector width");
140
141 // if signed, apply sign.
142 if(is_signed)
143 result = bv_utils.cond_negate(result, unpacked.sign);
144 else
145 {
146 // It's unclear what the behaviour for negative floats
147 // to integer shall be.
148 }
149
150 return result;
151}
152
154{
155 unbiased_floatt result;
156
157 result.sign=const_literal(src.get_sign());
158 result.NaN=const_literal(src.is_NaN());
159 result.infinity=const_literal(src.is_infinity());
160 result.exponent=bv_utils.build_constant(src.get_exponent(), spec.e);
161 result.fraction=bv_utils.build_constant(src.get_fraction(), spec.f+1);
162
163 return pack(bias(result));
164}
165
167{
168 PRECONDITION(src.size() == spec.width());
169
170 // Zero? NaN? Infinity?
171 auto unpacked = unpack(src);
172 auto is_special = prop.lor({unpacked.zero, unpacked.NaN, unpacked.infinity});
173
174 // add 2^f, where f is the number of fraction bits,
175 // by adding f to the exponent
176 auto magic_number = ieee_floatt{
178
179 auto magic_number_bv = build_constant(magic_number);
180
181 // abs(x) >= magic_number? If so, then there is no fractional part.
182 literalt ge_magic_number = relation(abs(src), relt::GE, magic_number_bv);
183
184 magic_number_bv.back() = src.back(); // copy sign bit
185
186 auto tmp1 = add_sub(src, magic_number_bv, false);
187
188 auto tmp2 = add_sub(tmp1, magic_number_bv, true);
189
190 // restore the original sign bit
191 tmp2.back() = src.back();
192
193 return bv_utils.select(prop.lor(is_special, ge_magic_number), src, tmp2);
194}
195
197 const bvt &src,
198 const ieee_float_spect &dest_spec)
199{
200 PRECONDITION(src.size() == spec.width());
201
202 #if 1
203 // Catch the special case in which we extend,
204 // e.g. single to double.
205 // In this case, rounding can be avoided,
206 // but a denormal number may be come normal.
207 // Be careful to exclude the difficult case
208 // when denormalised numbers in the old format
209 // can be converted to denormalised numbers in the
210 // new format. Note that this is rare and will only
211 // happen with very non-standard formats.
212
213 int sourceSmallestNormalExponent=-((1 << (spec.e - 1)) - 1);
214 int sourceSmallestDenormalExponent =
215 sourceSmallestNormalExponent - spec.f;
216
217 // Using the fact that f doesn't include the hidden bit
218
219 int destSmallestNormalExponent=-((1 << (dest_spec.e - 1)) - 1);
220
221 if(dest_spec.e>=spec.e &&
222 dest_spec.f>=spec.f &&
223 !(sourceSmallestDenormalExponent < destSmallestNormalExponent))
224 {
225 unbiased_floatt unpacked_src=unpack(src);
226 unbiased_floatt result;
227
228 // the fraction gets zero-padded
229 std::size_t padding=dest_spec.f-spec.f;
230 result.fraction=
231 bv_utils.concatenate(bv_utils.zeros(padding), unpacked_src.fraction);
232
233 // the exponent gets sign-extended
234 result.exponent=
235 bv_utils.sign_extension(unpacked_src.exponent, dest_spec.e);
236
237 // if the number was denormal and is normal in the new format,
238 // normalise it!
239 if(dest_spec.e > spec.e)
240 {
241 normalization_shift(result.fraction, result.exponent);
242 // normalization_shift unconditionally extends the exponent size to avoid
243 // arithmetic overflow, but this cannot have happened here as the exponent
244 // had already been extended to dest_spec's size
245 result.exponent.resize(dest_spec.e);
246 }
247
248 // the flags get copied
249 result.sign=unpacked_src.sign;
250 result.NaN=unpacked_src.NaN;
251 result.infinity=unpacked_src.infinity;
252
253 // no rounding needed!
254 spec=dest_spec;
255 return pack(bias(result));
256 }
257 else // NOLINT(readability/braces)
258 #endif
259 {
260 // we actually need to round
261 unbiased_floatt result=unpack(src);
262 spec=dest_spec;
263 return round_and_pack(result);
264 }
265}
266
268{
269 return prop.land(
270 !exponent_all_zeros(src),
271 !exponent_all_ones(src));
272}
273
276 const unbiased_floatt &src1,
277 const unbiased_floatt &src2)
278{
279 // extend both
280 bvt extended_exponent1=
281 bv_utils.sign_extension(src1.exponent, src1.exponent.size()+1);
282 bvt extended_exponent2=
283 bv_utils.sign_extension(src2.exponent, src2.exponent.size()+1);
284
285 PRECONDITION(extended_exponent1.size() == extended_exponent2.size());
286
287 // compute shift distance (here is the subtraction)
288 return bv_utils.sub(extended_exponent1, extended_exponent2);
289}
290
292 const bvt &src1,
293 const bvt &src2,
294 bool subtract)
295{
296 unbiased_floatt unpacked1=unpack(src1);
297 unbiased_floatt unpacked2=unpack(src2);
298
299 // subtract?
300 if(subtract)
301 unpacked2.sign=!unpacked2.sign;
302
303 // figure out which operand has the bigger exponent
304 const bvt exponent_difference=subtract_exponents(unpacked1, unpacked2);
305 literalt src2_bigger=exponent_difference.back();
306
307 const bvt bigger_exponent=
308 bv_utils.select(src2_bigger, unpacked2.exponent, unpacked1.exponent);
309
310 // swap fractions as needed
311 const bvt new_fraction1=
312 bv_utils.select(src2_bigger, unpacked2.fraction, unpacked1.fraction);
313
314 const bvt new_fraction2=
315 bv_utils.select(src2_bigger, unpacked1.fraction, unpacked2.fraction);
316
317 // compute distance
318 const bvt distance=bv_utils.absolute_value(exponent_difference);
319
320 // limit the distance: shifting more than f+3 bits is unnecessary
321 const bvt limited_dist=limit_distance(distance, spec.f+3);
322
323 // pad fractions with 2 zeros from below
324 const bvt fraction1_padded=
325 bv_utils.concatenate(bv_utils.zeros(3), new_fraction1);
326 const bvt fraction2_padded=
327 bv_utils.concatenate(bv_utils.zeros(3), new_fraction2);
328
329 // shift new_fraction2
330 literalt sticky_bit;
331 const bvt fraction1_shifted=fraction1_padded;
332 const bvt fraction2_shifted=sticky_right_shift(
333 fraction2_padded, limited_dist, sticky_bit);
334
335 // sticky bit: or of the bits lost by the right-shift
336 bvt fraction2_stickied=fraction2_shifted;
337 fraction2_stickied[0]=prop.lor(fraction2_shifted[0], sticky_bit);
338
339 // need to have two extra fraction bits for addition and rounding
340 const bvt fraction1_ext=
341 bv_utils.zero_extension(fraction1_shifted, fraction1_shifted.size()+2);
342 const bvt fraction2_ext=
343 bv_utils.zero_extension(fraction2_stickied, fraction2_stickied.size()+2);
344
345 unbiased_floatt result;
346
347 // now add/sub them
348 literalt subtract_lit=prop.lxor(unpacked1.sign, unpacked2.sign);
349 result.fraction=
350 bv_utils.add_sub(fraction1_ext, fraction2_ext, subtract_lit);
351
352 // sign of result
353 literalt fraction_sign=result.fraction.back();
354 result.fraction=bv_utils.absolute_value(result.fraction);
355
356 result.exponent=bigger_exponent;
357
358 // adjust the exponent for the fact that we added two bits to the fraction
359 result.exponent=
360 bv_utils.add(
361 bv_utils.sign_extension(result.exponent, result.exponent.size()+1),
362 bv_utils.build_constant(2, result.exponent.size()+1));
363
364 // NaN?
365 result.NaN=prop.lor(
366 prop.land(prop.land(unpacked1.infinity, unpacked2.infinity),
367 prop.lxor(unpacked1.sign, unpacked2.sign)),
368 prop.lor(unpacked1.NaN, unpacked2.NaN));
369
370 // infinity?
371 result.infinity=prop.land(
372 !result.NaN,
373 prop.lor(unpacked1.infinity, unpacked2.infinity));
374
375 // zero?
376 // Note that:
377 // 1. The zero flag isn't used apart from in divide and
378 // is only set on unpack
379 // 2. Subnormals mean that addition or subtraction can't round to 0,
380 // thus we can perform this test now
381 // 3. The rules for sign are different for zero
382 result.zero=prop.land(
383 !prop.lor(result.infinity, result.NaN),
384 !prop.lor(result.fraction));
385
386
387 // sign
388 literalt add_sub_sign=
389 prop.lxor(prop.lselect(src2_bigger, unpacked2.sign, unpacked1.sign),
390 fraction_sign);
391
392 literalt infinity_sign=
393 prop.lselect(unpacked1.infinity, unpacked1.sign, unpacked2.sign);
394
395 #if 1
396 literalt zero_sign=
397 prop.lselect(rounding_mode_bits.round_to_minus_inf,
398 prop.lor(unpacked1.sign, unpacked2.sign),
399 prop.land(unpacked1.sign, unpacked2.sign));
400
401 result.sign=prop.lselect(
402 result.infinity,
403 infinity_sign,
404 prop.lselect(result.zero,
405 zero_sign,
406 add_sub_sign));
407 #else
408 result.sign=prop.lselect(
409 result.infinity,
410 infinity_sign,
411 add_sub_sign);
412 #endif
413
414 #if 0
415 result.sign=const_literal(false);
416 result.fraction.resize(spec.f+1, const_literal(true));
417 result.exponent.resize(spec.e, const_literal(false));
418 result.NaN=const_literal(false);
419 result.infinity=const_literal(false);
420 // for(std::size_t i=0; i<result.fraction.size(); i++)
421 // result.fraction[i]=const_literal(true);
422
423 for(std::size_t i=0; i<result.fraction.size(); i++)
424 result.fraction[i]=new_fraction2[i];
425
426 return pack(bias(result));
427 #endif
428
429 return round_and_pack(result);
430}
431
434 const bvt &dist,
435 mp_integer limit)
436{
437 std::size_t nb_bits = address_bits(limit);
438
439 bvt upper_bits=dist;
440 upper_bits.erase(upper_bits.begin(), upper_bits.begin()+nb_bits);
441 literalt or_upper_bits=prop.lor(upper_bits);
442
443 bvt lower_bits=dist;
444 lower_bits.resize(nb_bits);
445
446 bvt result;
447 result.resize(lower_bits.size());
448
449 // bitwise or with or_upper_bits
450 for(std::size_t i=0; i<result.size(); i++)
451 result[i]=prop.lor(lower_bits[i], or_upper_bits);
452
453 return result;
454}
455
456bvt float_utilst::mul(const bvt &src1, const bvt &src2)
457{
458 // unpack
459 const unbiased_floatt unpacked1=unpack(src1);
460 const unbiased_floatt unpacked2=unpack(src2);
461
462 // zero-extend the fractions
463 const bvt fraction1=
464 bv_utils.zero_extension(unpacked1.fraction, unpacked1.fraction.size()*2);
465 const bvt fraction2=
466 bv_utils.zero_extension(unpacked2.fraction, unpacked2.fraction.size()*2);
467
468 // multiply fractions
469 unbiased_floatt result;
470 result.fraction=bv_utils.unsigned_multiplier(fraction1, fraction2);
471
472 // extend exponents to account for overflow
473 // add two bits, as we do extra arithmetic on it later
474 const bvt exponent1=
475 bv_utils.sign_extension(unpacked1.exponent, unpacked1.exponent.size()+2);
476 const bvt exponent2=
477 bv_utils.sign_extension(unpacked2.exponent, unpacked2.exponent.size()+2);
478
479 bvt added_exponent=bv_utils.add(exponent1, exponent2);
480
481 // adjust, we are thowing in an extra fraction bit
482 // it has been extended above
483 result.exponent=bv_utils.inc(added_exponent);
484
485 // new sign
486 result.sign=prop.lxor(unpacked1.sign, unpacked2.sign);
487
488 // infinity?
489 result.infinity=prop.lor(unpacked1.infinity, unpacked2.infinity);
490
491 // NaN?
492 {
493 bvt NaN_cond;
494
495 NaN_cond.push_back(is_NaN(src1));
496 NaN_cond.push_back(is_NaN(src2));
497
498 // infinity * 0 is NaN!
499 NaN_cond.push_back(prop.land(unpacked1.zero, unpacked2.infinity));
500 NaN_cond.push_back(prop.land(unpacked2.zero, unpacked1.infinity));
501
502 result.NaN=prop.lor(NaN_cond);
503 }
504
505 return round_and_pack(result);
506}
507
509 const bvt &multiply_lhs,
510 const bvt &multiply_rhs,
511 const bvt &addend)
512{
513 // Fused multiply-add: round(src1 * src2 + src3) with a single rounding.
514 // The product src1 * src2 is computed exactly (double-width fraction),
515 // then src3 is added, and the result is rounded once.
516
517 const unbiased_floatt unpacked_lhs = unpack(multiply_lhs);
518 const unbiased_floatt unpacked_rhs = unpack(multiply_rhs);
519 const unbiased_floatt unpacked_add = unpack(addend);
520
521 // --- Exact product a*b ---
522 const std::size_t frac_size = unpacked_lhs.fraction.size(); // f+1
523
524 bvt prod_fraction = bv_utils.unsigned_multiplier(
525 bv_utils.zero_extension(unpacked_lhs.fraction, frac_size * 2),
526 bv_utils.zero_extension(unpacked_rhs.fraction, frac_size * 2));
527 // Product fraction has width 2*(f+1) bits (double-width fraction w.r.t.
528 // inputs).
529 // The value is prod_fraction * 2^(prod_exponent - (prod_fraction.size()-1)).
530 // Keep full width for exact intermediate result.
531
532 bvt prod_exponent = bv_utils.add(
533 bv_utils.sign_extension(
534 unpacked_lhs.exponent, unpacked_lhs.exponent.size() + 2),
535 bv_utils.sign_extension(
536 unpacked_rhs.exponent, unpacked_rhs.exponent.size() + 2));
537 prod_exponent = bv_utils.inc(prod_exponent);
538
539 // When either multiplicand is zero, the product fraction is all zeros
540 // but prod_exponent is still the sum of the operand exponents, which can
541 // be very large. During alignment the addend would then be treated as
542 // the smaller operand and shifted out, losing its bits. Force
543 // prod_exponent to the minimum representable value in that case so the
544 // addend always dominates.
545 literalt product_is_zero = prop.lor(unpacked_lhs.zero, unpacked_rhs.zero);
546 bvt min_exponent = bv_utils.build_constant(
547 -(mp_integer(1) << (prod_exponent.size() - 2)), prod_exponent.size());
548 prod_exponent = bv_utils.select(product_is_zero, min_exponent, prod_exponent);
549
550 literalt prod_sign = prop.lxor(unpacked_lhs.sign, unpacked_rhs.sign);
551
552 // --- Align c's fraction to the product's wider format ---
553 // Product fraction: prod_width bits, binary point after MSB.
554 // c fraction: (f+1) bits. Pad on the right to match width, then
555 // adjust exponent to compensate.
556 const std::size_t prod_width = prod_fraction.size();
557 const std::size_t c_pad = prod_width - frac_size;
558 bvt c_fraction =
559 bv_utils.concatenate(bv_utils.zeros(c_pad), unpacked_add.fraction);
560 bvt c_exponent =
561 bv_utils.sign_extension(unpacked_add.exponent, prod_exponent.size());
562
563 // --- Add product + c (same logic as add_sub) ---
564 bvt exp_diff = bv_utils.sub(prod_exponent, c_exponent);
565 literalt c_bigger = exp_diff.back();
566
567 bvt bigger_exp = bv_utils.select(c_bigger, c_exponent, prod_exponent);
568 bvt big_frac = bv_utils.select(c_bigger, c_fraction, prod_fraction);
569 bvt small_frac = bv_utils.select(c_bigger, prod_fraction, c_fraction);
570
571 bvt distance = bv_utils.absolute_value(exp_diff);
572 bvt limited_dist = limit_distance(distance, mp_integer(prod_width + 3));
573
574 bvt big_padded = bv_utils.concatenate(bv_utils.zeros(3), big_frac);
575 bvt small_padded = bv_utils.concatenate(bv_utils.zeros(3), small_frac);
576
577 literalt sticky_bit;
578 bvt small_shifted =
579 sticky_right_shift(small_padded, limited_dist, sticky_bit);
580 small_shifted[0] = prop.lor(small_shifted[0], sticky_bit);
581
582 bvt big_ext = bv_utils.zero_extension(big_padded, big_padded.size() + 2);
583 bvt small_ext =
584 bv_utils.zero_extension(small_shifted, small_shifted.size() + 2);
585
586 literalt subtract_lit = prop.lxor(prod_sign, unpacked_add.sign);
587 bvt sum = bv_utils.add_sub(big_ext, small_ext, subtract_lit);
588
589 literalt fraction_sign = sum.back();
590 sum = bv_utils.absolute_value(sum);
591
592 unbiased_floatt result;
593 result.fraction = sum;
594 result.exponent = bv_utils.add(
595 bv_utils.sign_extension(bigger_exp, bigger_exp.size() + 1),
596 bv_utils.build_constant(2, bigger_exp.size() + 1));
597
598 // Sign
599 literalt add_sub_sign = prop.lxor(
600 prop.lselect(c_bigger, unpacked_add.sign, prod_sign), fraction_sign);
601
602 // NaN: any input NaN, inf*0, or inf+(-inf) in the addition
603 literalt prod_inf = prop.lor(unpacked_lhs.infinity, unpacked_rhs.infinity);
604 result.NaN = prop.lor(
605 {is_NaN(multiply_lhs),
606 is_NaN(multiply_rhs),
607 is_NaN(addend),
608 prop.land(unpacked_lhs.zero, unpacked_rhs.infinity),
609 prop.land(unpacked_rhs.zero, unpacked_lhs.infinity),
610 prop.land(
611 prop.land(prod_inf, unpacked_add.infinity),
612 prop.lxor(prod_sign, unpacked_add.sign))});
613
614 result.infinity =
615 prop.land(!result.NaN, prop.lor(prod_inf, unpacked_add.infinity));
616
617 result.zero = prop.land(
618 !prop.lor(result.infinity, result.NaN), !prop.lor(result.fraction));
619
620 literalt infinity_sign = prop.lselect(prod_inf, prod_sign, unpacked_add.sign);
621 literalt zero_sign = prop.lselect(
622 rounding_mode_bits.round_to_minus_inf,
623 prop.lor(prod_sign, unpacked_add.sign),
624 prop.land(prod_sign, unpacked_add.sign));
625
626 result.sign = prop.lselect(
627 result.infinity,
628 infinity_sign,
629 prop.lselect(result.zero, zero_sign, add_sub_sign));
630
631 return round_and_pack(result);
632}
633
634bvt float_utilst::div(const bvt &src1, const bvt &src2)
635{
636 // unpack
637 const unbiased_floatt unpacked1=unpack(src1);
638 const unbiased_floatt unpacked2=unpack(src2);
639
640 std::size_t div_width=unpacked1.fraction.size()*2+1;
641
642 // pad fraction1 with zeros
643 bvt fraction1=unpacked1.fraction;
644 fraction1.reserve(div_width);
645 while(fraction1.size()<div_width)
646 fraction1.insert(fraction1.begin(), const_literal(false));
647
648 // zero-extend fraction2
649 const bvt fraction2=
650 bv_utils.zero_extension(unpacked2.fraction, div_width);
651
652 // divide fractions
653 unbiased_floatt result;
654 bvt rem;
655 bv_utils.unsigned_divider(fraction1, fraction2, result.fraction, rem);
656
657 // is there a remainder?
658 literalt have_remainder=bv_utils.is_not_zero(rem);
659
660 // we throw this into the result, as one additional bit,
661 // to get the right rounding decision
662 result.fraction.insert(
663 result.fraction.begin(), have_remainder);
664
665 // We will subtract the exponents;
666 // to account for overflow, we add a bit.
667 // we add a second bit for the adjust by extra fraction bits
668 const bvt exponent1=
669 bv_utils.sign_extension(unpacked1.exponent, unpacked1.exponent.size()+2);
670 const bvt exponent2=
671 bv_utils.sign_extension(unpacked2.exponent, unpacked2.exponent.size()+2);
672
673 // subtract exponents
674 bvt added_exponent=bv_utils.sub(exponent1, exponent2);
675
676 // adjust, as we have thown in extra fraction bits
677 result.exponent=bv_utils.add(
678 added_exponent,
679 bv_utils.build_constant(spec.f, added_exponent.size()));
680
681 // new sign
682 result.sign=prop.lxor(unpacked1.sign, unpacked2.sign);
683
684 // Infinity? This happens when
685 // 1) dividing a non-nan/non-zero by zero, or
686 // 2) first operand is inf and second is non-nan and non-zero
687 // In particular, inf/0=inf.
688 result.infinity=
689 prop.lor(
690 prop.land(!unpacked1.zero,
691 prop.land(!unpacked1.NaN,
692 unpacked2.zero)),
693 prop.land(unpacked1.infinity,
694 prop.land(!unpacked2.NaN,
695 !unpacked2.zero)));
696
697 // NaN?
698 result.NaN=prop.lor(unpacked1.NaN,
699 prop.lor(unpacked2.NaN,
700 prop.lor(prop.land(unpacked1.zero, unpacked2.zero),
701 prop.land(unpacked1.infinity, unpacked2.infinity))));
702
703 // Division by infinity produces zero, unless we have NaN
704 literalt force_zero=
705 prop.land(!unpacked1.NaN, unpacked2.infinity);
706
707 result.fraction=bv_utils.select(force_zero,
708 bv_utils.zeros(result.fraction.size()), result.fraction);
709
710 return round_and_pack(result);
711}
712
713bvt float_utilst::rem(const bvt &src1, const bvt &src2)
714{
715 /* The semantics of floating-point remainder implemented as below
716 is the sensible one. Unfortunately this is not the one required
717 by IEEE-754 or fmod / remainder. Martin has discussed the
718 'correct' semantics with Christoph and Alberto at length as
719 well as talking to various hardware designers and we still
720 hasn't found a good way to implement them in a solver.
721 We have some approaches that are correct but they really
722 don't scale. */
723
724 const unbiased_floatt unpacked2 = unpack(src2);
725
726 // stub: do (src2.infinity ? src1 : (src1/src2)*src2))
727 return bv_utils.select(
728 unpacked2.infinity, src1, sub(src1, mul(div(src1, src2), src2)));
729}
730
732{
733 PRECONDITION(!src.empty());
734 bvt result=src;
735 literalt &sign_bit=result[result.size()-1];
737 return result;
738}
739
741{
742 PRECONDITION(!src.empty());
743 bvt result=src;
744 result[result.size()-1]=const_literal(false);
745 return result;
746}
747
749 const bvt &src1,
750 relt rel,
751 const bvt &src2)
752{
753 if(rel==relt::GT)
754 return relation(src2, relt::LT, src1); // swapped
755 else if(rel==relt::GE)
756 return relation(src2, relt::LE, src1); // swapped
757
758 PRECONDITION(rel == relt::EQ || rel == relt::LT || rel == relt::LE);
759
760 // special cases: -0 and 0 are equal
761 literalt is_zero1=is_zero(src1);
762 literalt is_zero2=is_zero(src2);
763 literalt both_zero=prop.land(is_zero1, is_zero2);
764
765 // NaN compares to nothing
766 literalt is_NaN1=is_NaN(src1);
767 literalt is_NaN2=is_NaN(src2);
768 literalt NaN=prop.lor(is_NaN1, is_NaN2);
769
770 if(rel==relt::LT || rel==relt::LE)
771 {
772 literalt bitwise_equal=bv_utils.equal(src1, src2);
773
774 // signs different? trivial! Unless Zero.
775
776 literalt signs_different=
777 prop.lxor(sign_bit(src1), sign_bit(src2));
778
779 // as long as the signs match: compare like unsigned numbers
780
781 // this works due to the BIAS
782 literalt less_than1=bv_utils.unsigned_less_than(src1, src2);
783
784 // if both are negative (and not the same), need to turn around!
785 literalt less_than2=
786 prop.lxor(less_than1, prop.land(sign_bit(src1), sign_bit(src2)));
787
788 literalt less_than3=
789 prop.lselect(signs_different,
790 sign_bit(src1),
791 less_than2);
792
793 if(rel==relt::LT)
794 {
795 bvt and_bv;
796 and_bv.push_back(less_than3);
797 and_bv.push_back(!bitwise_equal); // for the case of two negative numbers
798 and_bv.push_back(!both_zero);
799 and_bv.push_back(!NaN);
800
801 return prop.land(and_bv);
802 }
803 else if(rel==relt::LE)
804 {
805 bvt or_bv;
806 or_bv.push_back(less_than3);
807 or_bv.push_back(both_zero);
808 or_bv.push_back(bitwise_equal);
809
810 return prop.land(prop.lor(or_bv), !NaN);
811 }
812 else
814 }
815 else if(rel==relt::EQ)
816 {
817 literalt bitwise_equal=bv_utils.equal(src1, src2);
818
819 return prop.land(
820 prop.lor(bitwise_equal, both_zero),
821 !NaN);
822 }
823
824 // not reached
826 return const_literal(false);
827}
828
830{
831 PRECONDITION(!src.empty());
832 bvt all_but_sign;
833 all_but_sign=src;
834 all_but_sign.resize(all_but_sign.size()-1);
835 return bv_utils.is_zero(all_but_sign);
836}
837
839{
840 bvt and_bv;
841 and_bv.push_back(!sign_bit(src));
842 and_bv.push_back(exponent_all_ones(src));
843 and_bv.push_back(fraction_all_zeros(src));
844 return prop.land(and_bv);
845}
846
848{
849 return prop.land(
851 fraction_all_zeros(src));
852}
853
856{
857 return bv_utils.extract(src, spec.f, spec.f+spec.e-1);
858}
859
862{
863 return bv_utils.extract(src, 0, spec.f-1);
864}
865
867{
868 bvt and_bv;
869 and_bv.push_back(sign_bit(src));
870 and_bv.push_back(exponent_all_ones(src));
871 and_bv.push_back(fraction_all_zeros(src));
872 return prop.land(and_bv);
873}
874
876{
877 return prop.land(exponent_all_ones(src),
878 !fraction_all_zeros(src));
879}
880
882{
883 bvt exponent=src;
884
885 // removes the fractional part
886 exponent.erase(exponent.begin(), exponent.begin()+spec.f);
887
888 // removes the sign
889 exponent.resize(spec.e);
890
891 return bv_utils.is_all_ones(exponent);
892}
893
895{
896 bvt exponent=src;
897
898 // removes the fractional part
899 exponent.erase(exponent.begin(), exponent.begin()+spec.f);
900
901 // removes the sign
902 exponent.resize(spec.e);
903
904 return bv_utils.is_zero(exponent);
905}
906
908{
909 PRECONDITION(src.size() == spec.width());
910 // does not include hidden bit
911 bvt tmp=src;
912 tmp.resize(spec.f);
913 return bv_utils.is_zero(tmp);
914}
915
917void float_utilst::normalization_shift(bvt &fraction, bvt &exponent)
918{
919 #if 0
920 // this thing is quadratic!
921
922 bvt new_fraction=prop.new_variables(fraction.size());
923 bvt new_exponent=prop.new_variables(exponent.size());
924
925 // i is the shift distance
926 for(std::size_t i=0; i<fraction.size(); i++)
927 {
928 bvt equal;
929
930 // the bits above need to be zero
931 for(std::size_t j=0; j<i; j++)
932 equal.push_back(
933 !fraction[fraction.size()-1-j]);
934
935 // this one needs to be one
936 equal.push_back(fraction[fraction.size()-1-i]);
937
938 // iff all of that holds, we shift here!
939 literalt shift=prop.land(equal);
940
941 // build shifted value
942 bvt shifted_fraction=bv_utils.shift(fraction, bv_utilst::shiftt::SHIFT_LEFT, i);
943 bv_utils.cond_implies_equal(shift, shifted_fraction, new_fraction);
944
945 // build new exponent
946 bvt adjustment=bv_utils.build_constant(-i, exponent.size());
947 bvt added_exponent=bv_utils.add(exponent, adjustment);
948 bv_utils.cond_implies_equal(shift, added_exponent, new_exponent);
949 }
950
951 // Fraction all zero? It stays zero.
952 // The exponent is undefined in that case.
953 literalt fraction_all_zero=bv_utils.is_zero(fraction);
954 bvt zero_fraction;
955 zero_fraction.resize(fraction.size(), const_literal(false));
956 bv_utils.cond_implies_equal(fraction_all_zero, zero_fraction, new_fraction);
957
958 fraction=new_fraction;
959 exponent=new_exponent;
960
961 #else
962
963 // n-log-n alignment shifter.
964 // The worst-case shift is the number of fraction
965 // bits minus one, in case the fraction is one exactly.
966 PRECONDITION(!fraction.empty());
967 std::size_t depth = address_bits(fraction.size() - 1);
968
969 // sign-extend to ensure the arithmetic below cannot result in overflow/underflow
970 exponent =
971 bv_utils.sign_extension(exponent, std::max(depth, exponent.size() + 1));
972
973 bvt exponent_delta=bv_utils.zeros(exponent.size());
974
975 // Fraction smaller than the max distance? Pad up with zeros.
976 std::size_t max_distance = 1 << (depth - 1);
977
978 if(fraction.size() < max_distance)
979 fraction = bv_utils.zero_extension(fraction, max_distance);
980
981 for(int d=depth-1; d>=0; d--)
982 {
983 std::size_t distance=(1<<d);
984
985 INVARIANT(
986 fraction.size() >= distance, "fraction must be larger or equal distance");
987
988 // check if first 'distance'-many bits are zeros
989 const bvt prefix=bv_utils.extract_msb(fraction, distance);
990 literalt prefix_is_zero=bv_utils.is_zero(prefix);
991
992 // If so, shift the zeros out left by 'distance'.
993 // Otherwise, leave as is.
994 const bvt shifted=
995 bv_utils.shift(fraction, bv_utilst::shiftt::SHIFT_LEFT, distance);
996
997 fraction=
998 bv_utils.select(prefix_is_zero, shifted, fraction);
999
1000 // add corresponding weight to exponent
1001 INVARIANT(
1002 d < (signed)exponent_delta.size(),
1003 "depth must be smaller than exponent size");
1004 exponent_delta[d]=prefix_is_zero;
1005 }
1006
1007 exponent=bv_utils.sub(exponent, exponent_delta);
1008
1009 #endif
1010}
1011
1014{
1015 PRECONDITION(exponent.size() >= spec.e);
1016
1017 mp_integer bias=spec.bias();
1018
1019 // Is the exponent strictly less than -bias+1, i.e., exponent<-bias+1?
1020 // This is transformed to distance=(-bias+1)-exponent
1021 // i.e., distance>0
1022 // Note that 1-bias is the exponent represented by 0...01,
1023 // i.e. the exponent of the smallest normal number and thus the 'base'
1024 // exponent for subnormal numbers.
1025
1026#if 1
1027 // Need to sign extend to avoid overflow. Note that this is a
1028 // relatively rare problem as the value needs to be close to the top
1029 // of the exponent range and then range must not have been
1030 // previously extended as add, multiply, etc. do. This is primarily
1031 // to handle casting down from larger ranges.
1032 exponent=bv_utils.sign_extension(exponent, exponent.size() + 1);
1033#endif
1034
1035 bvt distance=bv_utils.sub(
1036 bv_utils.build_constant(-bias+1, exponent.size()), exponent);
1037
1038 // use sign bit
1039 literalt denormal=prop.land(
1040 !distance.back(),
1041 !bv_utils.is_zero(distance));
1042
1043#if 1
1044 // Care must be taken to not loose information required for the
1045 // guard and sticky bits. +3 is for the hidden, guard and sticky bits.
1046 if(fraction.size() < (spec.f + 3))
1047 {
1048 // Add zeros at the LSB end for the guard bit to shift into
1049 fraction=
1050 bv_utils.concatenate(bv_utils.zeros((spec.f + 3) - fraction.size()),
1051 fraction);
1052 }
1053
1054 bvt denormalisedFraction=fraction;
1055
1056 literalt sticky_bit=const_literal(false);
1057 denormalisedFraction =
1058 sticky_right_shift(fraction, distance, sticky_bit);
1059 denormalisedFraction[0]=prop.lor(denormalisedFraction[0], sticky_bit);
1060
1061 fraction=
1062 bv_utils.select(
1063 denormal,
1064 denormalisedFraction,
1065 fraction);
1066
1067#else
1068 fraction=
1069 bv_utils.select(
1070 denormal,
1071 bv_utils.shift(fraction, bv_utilst::LRIGHT, distance),
1072 fraction);
1073#endif
1074
1075 exponent=
1076 bv_utils.select(denormal,
1077 bv_utils.build_constant(-bias, exponent.size()),
1078 exponent);
1079}
1080
1082{
1083 // incoming: some fraction (with explicit 1),
1084 // some exponent without bias
1085 // outgoing: rounded, with right size, but still unpacked
1086
1087 bvt aligned_fraction=src.fraction,
1088 aligned_exponent=src.exponent;
1089
1090 {
1091 std::size_t exponent_bits = std::max(address_bits(spec.f), spec.e) + 1;
1092
1093 // before normalization, make sure exponent is large enough
1094 if(aligned_exponent.size()<exponent_bits)
1095 {
1096 // sign extend
1097 aligned_exponent=
1098 bv_utils.sign_extension(aligned_exponent, exponent_bits);
1099 }
1100 }
1101
1102 // align it!
1103 normalization_shift(aligned_fraction, aligned_exponent);
1104 denormalization_shift(aligned_fraction, aligned_exponent);
1105
1106 unbiased_floatt result;
1107 result.fraction=aligned_fraction;
1108 result.exponent=aligned_exponent;
1109 result.sign=src.sign;
1110 result.NaN=src.NaN;
1111 result.infinity=src.infinity;
1112
1113 round_fraction(result);
1114 round_exponent(result);
1115
1116 return result;
1117}
1118
1120{
1121 return pack(bias(rounder(src)));
1122}
1123
1126 const std::size_t dest_bits,
1127 const literalt sign,
1128 const bvt &fraction)
1129{
1130 PRECONDITION(dest_bits < fraction.size());
1131
1132 // we have too many fraction bits
1133 std::size_t extra_bits=fraction.size()-dest_bits;
1134
1135 // more than two extra bits are superflus, and are
1136 // turned into a sticky bit
1137
1138 literalt sticky_bit=const_literal(false);
1139
1140 if(extra_bits>=2)
1141 {
1142 // We keep most-significant bits, and thus the tail is made
1143 // of least-significant bits.
1144 bvt tail=bv_utils.extract(fraction, 0, extra_bits-2);
1145 sticky_bit=prop.lor(tail);
1146 }
1147
1148 // the rounding bit is the last extra bit
1149 INVARIANT(
1150 extra_bits >= 1, "the extra bits include at least the rounding bit");
1151 literalt rounding_bit=fraction[extra_bits-1];
1152
1153 // we get one bit of the fraction for some rounding decisions
1154 literalt rounding_least=fraction[extra_bits];
1155
1156 // round-to-nearest (ties to even)
1157 literalt round_to_even=
1158 prop.land(rounding_bit,
1159 prop.lor(rounding_least, sticky_bit));
1160
1161 // round up
1162 literalt round_to_plus_inf=
1163 prop.land(!sign,
1164 prop.lor(rounding_bit, sticky_bit));
1165
1166 // round down
1167 literalt round_to_minus_inf=
1168 prop.land(sign,
1169 prop.lor(rounding_bit, sticky_bit));
1170
1171 // round to zero
1172 literalt round_to_zero=
1173 const_literal(false);
1174
1175 // round-to-nearest (ties to away)
1176 literalt round_to_away = rounding_bit;
1177
1178 // now select appropriate one
1179 // clang-format off
1180 return prop.lselect(rounding_mode_bits.round_to_even, round_to_even,
1181 prop.lselect(rounding_mode_bits.round_to_plus_inf, round_to_plus_inf,
1182 prop.lselect(rounding_mode_bits.round_to_minus_inf, round_to_minus_inf,
1183 prop.lselect(rounding_mode_bits.round_to_zero, round_to_zero,
1184 prop.lselect(rounding_mode_bits.round_to_away, round_to_away,
1185 prop.new_variable()))))); // otherwise non-det
1186 // clang-format on
1187}
1188
1190{
1191 std::size_t fraction_size=spec.f+1;
1192
1193 // do we need to enlarge the fraction?
1194 if(result.fraction.size()<fraction_size)
1195 {
1196 // pad with zeros at bottom
1197 std::size_t padding=fraction_size-result.fraction.size();
1198
1199 result.fraction=bv_utils.concatenate(
1200 bv_utils.zeros(padding),
1201 result.fraction);
1202
1203 INVARIANT(
1204 result.fraction.size() == fraction_size,
1205 "sizes should be equal as result.fraction was zero-padded");
1206 }
1207 else if(result.fraction.size()==fraction_size) // it stays
1208 {
1209 // do nothing
1210 }
1211 else // fraction gets smaller -- rounding
1212 {
1213 std::size_t extra_bits=result.fraction.size()-fraction_size;
1214 INVARIANT(
1215 extra_bits >= 1,
1216 "the extra bits should at least include the rounding bit");
1217
1218 // this computes the rounding decision
1220 fraction_size, result.sign, result.fraction);
1221
1222 // chop off all the extra bits
1223 result.fraction=bv_utils.extract(
1224 result.fraction, extra_bits, result.fraction.size()-1);
1225
1226 INVARIANT(
1227 result.fraction.size() == fraction_size,
1228 "sizes should be equal as extra bits were chopped off from "
1229 "result.fraction");
1230
1231#if 0
1232 // *** does not catch when the overflow goes subnormal -> normal ***
1233 // incrementing the fraction might result in an overflow
1234 result.fraction=
1235 bv_utils.zero_extension(result.fraction, result.fraction.size()+1);
1236
1237 result.fraction=bv_utils.incrementer(result.fraction, increment);
1238
1239 literalt overflow=result.fraction.back();
1240
1241 // In case of an overflow, the exponent has to be incremented.
1242 // "Post normalization" is then required.
1243 result.exponent=
1244 bv_utils.incrementer(result.exponent, overflow);
1245
1246 // post normalization of the fraction
1247 literalt integer_part1=result.fraction.back();
1248 literalt integer_part0=result.fraction[result.fraction.size()-2];
1249 literalt new_integer_part=prop.lor(integer_part1, integer_part0);
1250
1251 result.fraction.resize(result.fraction.size()-1);
1252 result.fraction.back()=new_integer_part;
1253
1254#else
1255 // When incrementing due to rounding there are two edge
1256 // cases we need to be aware of:
1257 // 1. If the number is normal, the increment can overflow.
1258 // In this case we need to increment the exponent and
1259 // set the MSB of the fraction to 1.
1260 // 2. If the number is the largest subnormal, the increment
1261 // can change the MSB making it normal. Thus the exponent
1262 // must be incremented but the fraction will be OK.
1263 literalt oldMSB=result.fraction.back();
1264
1265 result.fraction=bv_utils.incrementer(result.fraction, increment);
1266
1267 // Normal overflow when old MSB == 1 and new MSB == 0
1268 literalt overflow=prop.land(oldMSB, neg(result.fraction.back()));
1269
1270 // Subnormal to normal transition when old MSB == 0 and new MSB == 1
1271 literalt subnormal_to_normal=
1272 prop.land(neg(oldMSB), result.fraction.back());
1273
1274 // In case of an overflow or subnormal to normal conversion,
1275 // the exponent has to be incremented.
1276 result.exponent=
1277 bv_utils.incrementer(result.exponent,
1278 prop.lor(overflow, subnormal_to_normal));
1279
1280 // post normalization of the fraction
1281 // In the case of overflow, set the MSB to 1
1282 // The subnormal case will have (only) the MSB set to 1
1283 result.fraction.back()=prop.lor(result.fraction.back(), overflow);
1284#endif
1285 }
1286}
1287
1289{
1290 PRECONDITION(result.exponent.size() >= spec.e);
1291
1292 // do we need to enlarge the exponent?
1293 if(result.exponent.size() == spec.e) // it stays
1294 {
1295 // do nothing
1296 }
1297 else // exponent gets smaller -- chop off top bits
1298 {
1299 bvt old_exponent=result.exponent;
1300 result.exponent.resize(spec.e);
1301
1302 // max_exponent is the maximum representable
1303 // i.e. 1 higher than the maximum possible for a normal number
1304 bvt max_exponent=
1305 bv_utils.build_constant(
1306 spec.max_exponent()-spec.bias(), old_exponent.size());
1307
1308 // the exponent is garbage if the fractional is zero
1309
1310 literalt exponent_too_large=
1311 prop.land(
1312 !bv_utils.signed_less_than(old_exponent, max_exponent),
1313 !bv_utils.is_zero(result.fraction));
1314
1315#if 1
1316 // Directed rounding modes round overflow to the maximum normal
1317 // depending on the particular mode and the sign
1318 literalt overflow_to_inf=
1319 prop.lor(rounding_mode_bits.round_to_even,
1320 prop.lor(prop.land(rounding_mode_bits.round_to_plus_inf,
1321 !result.sign),
1322 prop.land(rounding_mode_bits.round_to_minus_inf,
1323 result.sign)));
1324
1325 literalt set_to_max=
1326 prop.land(exponent_too_large, !overflow_to_inf);
1327
1328
1329 bvt largest_normal_exponent=
1330 bv_utils.build_constant(
1331 spec.max_exponent()-(spec.bias() + 1), result.exponent.size());
1332
1333 result.exponent=
1334 bv_utils.select(set_to_max, largest_normal_exponent, result.exponent);
1335
1336 result.fraction=
1337 bv_utils.select(set_to_max,
1338 bv_utils.inverted(bv_utils.zeros(result.fraction.size())),
1339 result.fraction);
1340
1341 result.infinity=prop.lor(result.infinity,
1342 prop.land(exponent_too_large,
1343 overflow_to_inf));
1344#else
1345 result.infinity=prop.lor(result.infinity, exponent_too_large);
1346#endif
1347 }
1348}
1349
1352{
1353 PRECONDITION(src.fraction.size() == spec.f + 1);
1354
1355 biased_floatt result;
1356
1357 result.sign=src.sign;
1358 result.NaN=src.NaN;
1359 result.infinity=src.infinity;
1360
1361 // we need to bias the new exponent
1362 result.exponent=add_bias(src.exponent);
1363
1364 // strip off hidden bit
1365
1366 literalt hidden_bit=src.fraction[src.fraction.size()-1];
1367 literalt denormal=!hidden_bit;
1368
1369 result.fraction=src.fraction;
1370 result.fraction.resize(spec.f);
1371
1372 // make exponent zero if its denormal
1373 // (includes zero)
1374 for(std::size_t i=0; i<result.exponent.size(); i++)
1375 result.exponent[i]=
1376 prop.land(result.exponent[i], !denormal);
1377
1378 return result;
1379}
1380
1382{
1383 PRECONDITION(src.size() == spec.e);
1384
1385 return bv_utils.add(
1386 src,
1387 bv_utils.build_constant(spec.bias(), spec.e));
1388}
1389
1391{
1392 PRECONDITION(src.size() == spec.e);
1393
1394 return bv_utils.sub(
1395 src,
1396 bv_utils.build_constant(spec.bias(), spec.e));
1397}
1398
1400{
1401 PRECONDITION(src.size() == spec.width());
1402
1403 unbiased_floatt result;
1404
1405 result.sign=sign_bit(src);
1406
1407 result.fraction=get_fraction(src);
1408 result.fraction.push_back(is_normal(src)); // add hidden bit
1409
1410 result.exponent=get_exponent(src);
1411 CHECK_RETURN(result.exponent.size() == spec.e);
1412
1413 // unbias the exponent
1414 literalt denormal=bv_utils.is_zero(result.exponent);
1415
1416 result.exponent=
1417 bv_utils.select(denormal,
1418 bv_utils.build_constant(-spec.bias()+1, spec.e),
1419 sub_bias(result.exponent));
1420
1421 result.infinity=is_infinity(src);
1422 result.zero=is_zero(src);
1423 result.NaN=is_NaN(src);
1424
1425 return result;
1426}
1427
1429{
1430 PRECONDITION(src.fraction.size() == spec.f);
1431 PRECONDITION(src.exponent.size() == spec.e);
1432
1433 bvt result;
1434 result.resize(spec.width());
1435
1436 // do sign
1437 // we make this 'false' for NaN
1438 result[result.size()-1]=
1439 prop.lselect(src.NaN, const_literal(false), src.sign);
1440
1441 literalt infinity_or_NaN=
1442 prop.lor(src.NaN, src.infinity);
1443
1444 // just copy fraction
1445 for(std::size_t i=0; i<spec.f; i++)
1446 result[i]=prop.land(src.fraction[i], !infinity_or_NaN);
1447
1448 result[0]=prop.lor(result[0], src.NaN);
1449
1450 // do exponent
1451 for(std::size_t i=0; i<spec.e; i++)
1452 result[i+spec.f]=prop.lor(
1453 src.exponent[i],
1454 infinity_or_NaN);
1455
1456 return result;
1457}
1458
1460{
1461 mp_integer int_value=0;
1462
1463 for(std::size_t i=0; i<src.size(); i++)
1464 int_value+=power(2, i)*prop.l_get(src[i]).is_true();
1465
1466 ieee_float_valuet result;
1467 result.spec=spec;
1468 result.unpack(int_value);
1469
1470 return result;
1471}
1472
1474 const bvt &op,
1475 const bvt &dist,
1476 literalt &sticky)
1477{
1478 std::size_t d=1;
1479 bvt result=op;
1480 sticky=const_literal(false);
1481
1482 for(std::size_t stage=0; stage<dist.size(); stage++)
1483 {
1484 if(dist[stage]!=const_literal(false))
1485 {
1486 bvt tmp=bv_utils.shift(result, bv_utilst::shiftt::SHIFT_LRIGHT, d);
1487
1488 bvt lost_bits;
1489
1490 if(d<=result.size())
1491 lost_bits=bv_utils.extract(result, 0, d-1);
1492 else
1493 lost_bits=result;
1494
1495 sticky=prop.lor(
1496 prop.land(dist[stage], prop.lor(lost_bits)),
1497 sticky);
1498
1499 result=bv_utils.select(dist[stage], tmp, result);
1500 }
1501
1502 d=d<<1;
1503 }
1504
1505 return result;
1506}
1507
1509 const bvt &src1,
1510 const bvt &)
1511{
1512 return src1;
1513}
1514
1516 const bvt &op0,
1517 const bvt &)
1518{
1519 return op0;
1520}
std::size_t address_bits(const mp_integer &size)
ceil(log2(size))
mp_integer power(const mp_integer &base, const mp_integer &exponent)
A multi-precision implementation of the power operator.
unbiased_floatt rounder(const unbiased_floatt &)
bvt to_integer(const bvt &src, std::size_t int_width, bool is_signed)
literalt is_NaN(const bvt &)
virtual void normalization_shift(bvt &fraction, bvt &exponent)
normalize fraction/exponent pair returns 'zero' if fraction is zero
bv_utilst bv_utils
bvt debug2(const bvt &op0, const bvt &op1)
virtual bvt rem(const bvt &src1, const bvt &src2)
bvt round_to_integral(const bvt &)
literalt is_plus_inf(const bvt &)
ieee_float_valuet get(const bvt &) const
literalt is_infinity(const bvt &)
void set_rounding_mode(const bvt &)
void round_exponent(unbiased_floatt &result)
void round_fraction(unbiased_floatt &result)
bvt sticky_right_shift(const bvt &op, const bvt &dist, literalt &sticky)
unbiased_floatt unpack(const bvt &)
bvt from_unsigned_integer(const bvt &)
virtual bvt mul(const bvt &src1, const bvt &src2)
bvt debug1(const bvt &op0, const bvt &op1)
bvt add_bias(const bvt &exponent)
bvt round_and_pack(const unbiased_floatt &)
bvt subtract_exponents(const unbiased_floatt &src1, const unbiased_floatt &src2)
Subtracts the exponents.
bvt get_fraction(const bvt &)
Gets the fraction without hidden bit in a floating-point bit-vector src.
literalt is_minus_inf(const bvt &)
literalt fraction_rounding_decision(const std::size_t dest_bits, const literalt sign, const bvt &fraction)
rounding decision for fraction using sticky bit
bvt get_exponent(const bvt &)
Gets the unbiased exponent in a floating-point bit-vector.
void denormalization_shift(bvt &fraction, bvt &exponent)
make sure exponent is not too small; the exponent is unbiased
bvt to_unsigned_integer(const bvt &src, std::size_t int_width)
bvt build_constant(const ieee_float_valuet &)
virtual bvt div(const bvt &src1, const bvt &src2)
bvt negate(const bvt &)
literalt exponent_all_zeros(const bvt &)
literalt fraction_all_zeros(const bvt &)
bvt fma(const bvt &multiply_lhs, const bvt &multiply_rhs, const bvt &addend)
Fused multiply-add: round(multiply_lhs * multiply_rhs + addend) with a single rounding step.
bvt from_signed_integer(const bvt &)
literalt is_zero(const bvt &)
bvt sub(const bvt &src1, const bvt &src2)
bvt sub_bias(const bvt &exponent)
bvt limit_distance(const bvt &dist, mp_integer limit)
Limits the shift distance.
bvt conversion(const bvt &src, const ieee_float_spect &dest_spec)
bvt pack(const biased_floatt &)
virtual bvt add_sub(const bvt &src1, const bvt &src2, bool subtract)
bvt abs(const bvt &)
static literalt sign_bit(const bvt &src)
Definition float_utils.h:98
ieee_float_spect spec
Definition float_utils.h:94
literalt exponent_all_ones(const bvt &)
bvt to_signed_integer(const bvt &src, std::size_t int_width)
literalt is_normal(const bvt &)
literalt relation(const bvt &src1, relt rel, const bvt &src2)
rounding_mode_bitst rounding_mode_bits
Definition float_utils.h:73
biased_floatt bias(const unbiased_floatt &)
takes an unbiased float, and applies the bias
std::size_t f
Definition ieee_float.h:26
std::size_t e
Definition ieee_float.h:26
An IEEE 754 floating-point value, including specificiation.
Definition ieee_float.h:117
bool is_NaN() const
Definition ieee_float.h:259
ieee_float_spect spec
Definition ieee_float.h:119
bool get_sign() const
Definition ieee_float.h:254
const mp_integer & get_fraction() const
Definition ieee_float.h:264
void unpack(const mp_integer &)
bool is_infinity() const
Definition ieee_float.h:260
const mp_integer & get_exponent() const
Definition ieee_float.h:263
An IEEE 754 value plus a rounding mode, enabling operations with rounding on values.
Definition ieee_float.h:369
literalt neg(literalt a)
Definition literal.h:193
std::vector< literalt > bvt
Definition literal.h:201
literalt const_literal(bool value)
Definition literal.h:188
BigInt mp_integer
Definition smt_terms.h:17
#define CHECK_RETURN(CONDITION)
Definition invariant.h:495
#define UNREACHABLE
This should be used to mark dead code.
Definition invariant.h:525
#define PRECONDITION(CONDITION)
Definition invariant.h:463
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
bool is_signed(const typet &t)
Convenience function – is the type signed?
Definition util.cpp:45