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