CBMC
Loading...
Searching...
No Matches
float_bv.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#include "float_bv.h"
10
11#include <algorithm>
12
13#include <util/arith_tools.h>
14#include <util/bitvector_expr.h>
16#include <util/floatbv_expr.h>
17#include <util/std_expr.h>
18
19exprt float_bvt::convert(const exprt &expr) const
20{
21 if(expr.id()==ID_abs)
22 return abs(to_abs_expr(expr).op(), get_spec(expr));
23 else if(expr.id()==ID_unary_minus)
24 return negation(to_unary_minus_expr(expr).op(), get_spec(expr));
25 else if(expr.id()==ID_ieee_float_equal)
26 {
27 const auto &equal_expr = to_ieee_float_equal_expr(expr);
28 return is_equal(
29 equal_expr.lhs(), equal_expr.rhs(), get_spec(equal_expr.lhs()));
30 }
31 else if(expr.id()==ID_ieee_float_notequal)
32 {
34 return not_exprt(is_equal(
36 }
37 else if(expr.id()==ID_floatbv_typecast)
38 {
40 const auto &op = floatbv_typecast_expr.op();
41 const typet &src_type = floatbv_typecast_expr.op().type();
43 const auto &rounding_mode = floatbv_typecast_expr.rounding_mode();
44
45 if(dest_type.id()==ID_signedbv &&
46 src_type.id()==ID_floatbv) // float -> signed
47 return to_signed_integer(
48 op,
49 to_signedbv_type(dest_type).get_width(),
50 rounding_mode,
51 get_spec(op));
52 else if(dest_type.id()==ID_unsignedbv &&
53 src_type.id()==ID_floatbv) // float -> unsigned
55 op,
56 to_unsignedbv_type(dest_type).get_width(),
57 rounding_mode,
58 get_spec(op));
59 else if(src_type.id()==ID_signedbv &&
60 dest_type.id()==ID_floatbv) // signed -> float
61 return from_signed_integer(op, rounding_mode, get_spec(expr));
62 else if(src_type.id()==ID_unsignedbv &&
63 dest_type.id()==ID_floatbv) // unsigned -> float
64 {
65 return from_unsigned_integer(op, rounding_mode, get_spec(expr));
66 }
67 else if(dest_type.id()==ID_floatbv &&
68 src_type.id()==ID_floatbv) // float -> float
69 {
70 return conversion(op, rounding_mode, get_spec(op), get_spec(expr));
71 }
72 else
73 return nil_exprt();
74 }
75 else if(
76 expr.id() == ID_typecast && expr.is_boolean() &&
77 to_typecast_expr(expr).op().type().id() == ID_floatbv) // float -> bool
78 {
79 return not_exprt(is_zero(to_typecast_expr(expr).op()));
80 }
81 else if(
82 expr.id() == ID_typecast && expr.type().id() == ID_bv &&
83 to_typecast_expr(expr).op().type().id() == ID_floatbv) // float -> raw bv
84 {
85 const typecast_exprt &tc = to_typecast_expr(expr);
87 const floatbv_typet &src_type = to_floatbv_type(tc.op().type());
88 if(
89 dest_type.get_width() != src_type.get_width() ||
90 dest_type.get_width() == 0)
91 {
92 return nil_exprt{};
93 }
94
95 return extractbits_exprt{to_typecast_expr(expr).op(), 0, dest_type};
96 }
97 else if(expr.id()==ID_floatbv_plus)
98 {
99 const auto &float_expr = to_ieee_float_op_expr(expr);
100 return add_sub(
101 false,
102 float_expr.lhs(),
103 float_expr.rhs(),
104 float_expr.rounding_mode(),
105 get_spec(expr));
106 }
107 else if(expr.id()==ID_floatbv_minus)
108 {
109 const auto &float_expr = to_ieee_float_op_expr(expr);
110 return add_sub(
111 true,
112 float_expr.lhs(),
113 float_expr.rhs(),
114 float_expr.rounding_mode(),
115 get_spec(expr));
116 }
117 else if(expr.id()==ID_floatbv_mult)
118 {
119 const auto &float_expr = to_ieee_float_op_expr(expr);
120 return mul(
121 float_expr.lhs(),
122 float_expr.rhs(),
123 float_expr.rounding_mode(),
124 get_spec(expr));
125 }
126 else if(expr.id()==ID_floatbv_div)
127 {
128 const auto &float_expr = to_ieee_float_op_expr(expr);
129 return div(
130 float_expr.lhs(),
131 float_expr.rhs(),
132 float_expr.rounding_mode(),
133 get_spec(expr));
134 }
135 else if(expr.id() == ID_floatbv_fma)
136 {
137 const auto &fma_expr = to_floatbv_fma_expr(expr);
138 const ieee_float_spect spec{to_floatbv_type(fma_expr.type())};
139 return fma(
140 fma_expr.op_multiply_lhs(),
141 fma_expr.op_multiply_rhs(),
142 fma_expr.op_add(),
143 fma_expr.rounding_mode(),
144 spec);
145 }
146 else if(expr.id()==ID_isnan)
147 {
148 const auto &op = to_unary_expr(expr).op();
149 return isnan(op, get_spec(op));
150 }
151 else if(expr.id()==ID_isfinite)
152 {
153 const auto &op = to_unary_expr(expr).op();
154 return isfinite(op, get_spec(op));
155 }
156 else if(expr.id()==ID_isinf)
157 {
158 const auto &op = to_unary_expr(expr).op();
159 return isinf(op, get_spec(op));
160 }
161 else if(expr.id()==ID_isnormal)
162 {
163 const auto &op = to_unary_expr(expr).op();
164 return isnormal(op, get_spec(op));
165 }
166 else if(expr.id()==ID_lt)
167 {
168 const auto &rel_expr = to_binary_relation_expr(expr);
169 return relation(
170 rel_expr.lhs(), relt::LT, rel_expr.rhs(), get_spec(rel_expr.lhs()));
171 }
172 else if(expr.id()==ID_gt)
173 {
174 const auto &rel_expr = to_binary_relation_expr(expr);
175 return relation(
176 rel_expr.lhs(), relt::GT, rel_expr.rhs(), get_spec(rel_expr.lhs()));
177 }
178 else if(expr.id()==ID_le)
179 {
180 const auto &rel_expr = to_binary_relation_expr(expr);
181 return relation(
182 rel_expr.lhs(), relt::LE, rel_expr.rhs(), get_spec(rel_expr.lhs()));
183 }
184 else if(expr.id()==ID_ge)
185 {
186 const auto &rel_expr = to_binary_relation_expr(expr);
187 return relation(
188 rel_expr.lhs(), relt::GE, rel_expr.rhs(), get_spec(rel_expr.lhs()));
189 }
190 else if(expr.id()==ID_sign)
191 return sign_bit(to_unary_expr(expr).op());
192
193 return nil_exprt();
194}
195
197{
198 const floatbv_typet &type=to_floatbv_type(expr.type());
199 return ieee_float_spect(type);
200}
201
203{
204 // we mask away the sign bit, which is the most significant bit
205 const mp_integer v = power(2, spec.width() - 1) - 1;
206
207 const constant_exprt mask(integer2bvrep(v, spec.width()), op.type());
208
209 return bitand_exprt(op, mask);
210}
211
213{
214 // we flip the sign bit with an xor
215 const mp_integer v = power(2, spec.width() - 1);
216
217 constant_exprt mask(integer2bvrep(v, spec.width()), op.type());
218
219 return bitxor_exprt(op, mask);
220}
221
223 const exprt &src0,
224 const exprt &src1,
225 const ieee_float_spect &spec)
226{
227 // special cases: -0 and 0 are equal
228 const exprt is_zero0 = is_zero(src0);
229 const exprt is_zero1 = is_zero(src1);
231
232 // NaN compares to nothing
233 exprt isnan0=isnan(src0, spec);
234 exprt isnan1=isnan(src1, spec);
235 const or_exprt nan(isnan0, isnan1);
236
238
239 return and_exprt(
241 not_exprt(nan));
242}
243
245{
246 // we mask away the sign bit, which is the most significant bit
247 const floatbv_typet &type=to_floatbv_type(src.type());
248 std::size_t width=type.get_width();
249
250 const mp_integer v = power(2, width - 1) - 1;
251
252 constant_exprt mask(integer2bvrep(v, width), src.type());
253
254 ieee_float_valuet z(type);
255 z.make_zero();
256
257 return equal_exprt(bitand_exprt(src, mask), z.to_expr());
258}
259
261 const exprt &src,
262 const ieee_float_spect &spec)
263{
264 exprt exponent=get_exponent(src, spec);
265 exprt all_ones=to_unsignedbv_type(exponent.type()).largest_expr();
266 return equal_exprt(exponent, all_ones);
267}
268
270 const exprt &src,
271 const ieee_float_spect &spec)
272{
273 exprt exponent=get_exponent(src, spec);
274 exprt all_zeros=to_unsignedbv_type(exponent.type()).zero_expr();
275 return equal_exprt(exponent, all_zeros);
276}
277
279 const exprt &src,
280 const ieee_float_spect &spec)
281{
282 // does not include hidden bit
283 exprt fraction=get_fraction(src, spec);
284 exprt all_zeros=to_unsignedbv_type(fraction.type()).zero_expr();
285 return equal_exprt(fraction, all_zeros);
286}
287
305
307{
309 std::size_t width=bv_type.get_width();
310 return extractbit_exprt(op, width-1);
311}
312
314 const exprt &src,
315 const exprt &rm,
316 const ieee_float_spect &spec) const
317{
318 std::size_t src_width=to_signedbv_type(src.type()).get_width();
319
320 unbiased_floatt result;
321
322 // we need to adjust for negative integers
323 result.sign=sign_bit(src);
324
325 result.fraction=
327
328 // build an exponent (unbiased) -- this is signed!
329 result.exponent=
331 src_width-1,
333
334 return rounder(result, rm, spec);
335}
336
338 const exprt &src,
339 const exprt &rm,
340 const ieee_float_spect &spec) const
341{
342 unbiased_floatt result;
343
344 result.fraction=src;
345
346 std::size_t src_width=to_unsignedbv_type(src.type()).get_width();
347
348 // build an exponent (unbiased) -- this is signed!
349 result.exponent=
351 src_width-1,
353
354 result.sign=false_exprt();
355
356 return rounder(result, rm, spec);
357}
358
360 const exprt &src,
361 std::size_t dest_width,
362 const exprt &rm,
363 const ieee_float_spect &spec)
364{
365 return to_integer(src, dest_width, true, rm, spec);
366}
367
369 const exprt &src,
370 std::size_t dest_width,
371 const exprt &rm,
372 const ieee_float_spect &spec)
373{
374 return to_integer(src, dest_width, false, rm, spec);
375}
376
378 const exprt &src,
379 std::size_t dest_width,
380 bool is_signed,
381 const exprt &rm,
382 const ieee_float_spect &spec)
383{
384 // Keep in sync with float_utilst::to_integer — the body below is a
385 // line-for-line translation of that function between the exprt and
386 // literalt/bvt APIs.
387
388 const unbiased_floatt unpacked=unpack(src, spec);
389
390 rounding_mode_bitst rounding_mode_bits(rm);
391
392 // Right now hard-wired to round-to-zero, which is
393 // the usual case in ANSI-C.
394
395 const std::size_t fraction_width =
396 to_unsignedbv_type(unpacked.fraction.type()).get_width();
397
398 // Extend the fraction to dest_width if needed, padding with zeros
399 // at the LSB end (like float_utilst does).
400 exprt fraction = unpacked.fraction;
401 std::size_t effective_width = fraction_width;
402
403 if(dest_width > fraction_width)
404 {
406 fraction = concatenation_exprt(
407 fraction,
408 from_integer(0, unsignedbv_typet(dest_width - fraction_width)),
410 }
411
412 // if the exponent is positive, shift right by (effective_width - 1) minus
413 // the exponent. The shift distance is built in a signed type wide enough to
414 // hold both `effective_width - 1` and the (sign-extended) exponent, so it
415 // does not wrap for wide destination types -- e.g. a narrow source such as
416 // _Float16 (spec.e = 5) converted to a 64-bit integer. Keep in sync with
417 // float_utilst::to_integer.
418 const signedbv_typet distance_type(std::max(
419 static_cast<std::size_t>(spec.e), address_bits(effective_width) + 1));
420 const exprt offset = from_integer(effective_width - 1, distance_type);
421 const minus_exprt distance(
422 offset, typecast_exprt(unpacked.exponent, distance_type));
423 const lshr_exprt shift_result(fraction, distance);
424
425 // if the exponent is negative, we have zero anyways
426 exprt result=shift_result;
427 const sign_exprt exponent_sign(unpacked.exponent);
428
429 result=
430 if_exprt(exponent_sign, from_integer(0, result.type()), result);
431
432 // chop out the right number of bits from the result
433 typet result_type=
435 static_cast<typet>(unsignedbv_typet(dest_width));
436
437 result=typecast_exprt(result, result_type);
438
439 // if signed, apply sign.
440 if(is_signed)
441 {
442 result=if_exprt(
443 unpacked.sign, unary_minus_exprt(result), result);
444 }
445 else
446 {
447 // It's unclear what the behaviour for negative floats
448 // to integer shall be.
449 }
450
451 return result;
452}
453
455 const exprt &src,
456 const exprt &rm,
458 const ieee_float_spect &dest_spec) const
459{
460 // Catch the special case in which we extend,
461 // e.g. single to double.
462 // In this case, rounding can be avoided,
463 // but a denormal number may be come normal.
464 // Be careful to exclude the difficult case
465 // when denormalised numbers in the old format
466 // can be converted to denormalised numbers in the
467 // new format. Note that this is rare and will only
468 // happen with very non-standard formats.
469
470 int sourceSmallestNormalExponent = -((1 << (src_spec.e - 1)) - 1);
473
474 // Using the fact that f doesn't include the hidden bit
475
476 int destSmallestNormalExponent = -((1 << (dest_spec.e - 1)) - 1);
477
478 if(dest_spec.e>=src_spec.e &&
479 dest_spec.f>=src_spec.f &&
481 {
483 unbiased_floatt result;
484
485 // the fraction gets zero-padded
486 std::size_t padding=dest_spec.f-src_spec.f;
487 result.fraction=
489 unpacked_src.fraction,
492
493 // the exponent gets sign-extended
494 INVARIANT(
495 unpacked_src.exponent.type().id() == ID_signedbv,
496 "the exponent needs to have a signed type");
497 result.exponent=
499
500 // if the number was denormal and is normal in the new format,
501 // normalise it!
502 if(dest_spec.e > src_spec.e)
503 {
504 normalization_shift(result.fraction, result.exponent);
505 // normalization_shift unconditionally extends the exponent size to avoid
506 // arithmetic overflow, but this cannot have happened here as the exponent
507 // had already been extended to dest_spec's size
508 result.exponent =
510 }
511
512 // the flags get copied
513 result.sign=unpacked_src.sign;
514 result.NaN=unpacked_src.NaN;
515 result.infinity=unpacked_src.infinity;
516
517 // no rounding needed!
518 return pack(bias(result, dest_spec), dest_spec);
519 }
520 else
521 {
522 // we actually need to round
523 unbiased_floatt result=unpack(src, src_spec);
524 return rounder(result, rm, dest_spec);
525 }
526}
527
529 const exprt &src,
530 const ieee_float_spect &spec)
531{
532 return and_exprt(
533 not_exprt(exponent_all_zeros(src, spec)),
534 not_exprt(exponent_all_ones(src, spec)));
535}
536
539 const unbiased_floatt &src1,
540 const unbiased_floatt &src2)
541{
542 // extend both by one bit
543 std::size_t old_width1=to_signedbv_type(src1.exponent.type()).get_width();
544 std::size_t old_width2=to_signedbv_type(src2.exponent.type()).get_width();
546
548 src1.exponent, signedbv_typet(old_width1 + 1));
549
551 src2.exponent, signedbv_typet(old_width2 + 1));
552
553 // compute shift distance (here is the subtraction)
555}
556
558 bool subtract,
559 const exprt &op0,
560 const exprt &op1,
561 const exprt &rm,
562 const ieee_float_spect &spec) const
563{
566
567 // subtract?
568 if(subtract)
569 unpacked2.sign=not_exprt(unpacked2.sign);
570
571 // figure out which operand has the bigger exponent
574
576 if_exprt(src2_bigger, unpacked2.exponent, unpacked1.exponent);
577
578 // swap fractions as needed
579 const exprt new_fraction1=
580 if_exprt(src2_bigger, unpacked2.fraction, unpacked1.fraction);
581
582 const exprt new_fraction2=
583 if_exprt(src2_bigger, unpacked1.fraction, unpacked2.fraction);
584
585 // compute distance
586 const exprt distance=
588
589 // limit the distance: shifting more than f+3 bits is unnecessary
590 const exprt limited_dist=limit_distance(distance, spec.f+3);
591
592 // pad fractions with 3 zeros from below
594 // add 4 to spec.f because unpacked new_fraction has the hidden bit
599
600 // shift new_fraction2
605
606 // sticky bit: 'or' of the bits lost by the right-shift
610 from_integer(0, unsignedbv_typet(spec.f + 3)),
612 fraction2_shifted.type()));
613
614 // need to have two extra fraction bits for addition and rounding
615 const exprt fraction1_ext=
617 const exprt fraction2_ext=
619
620 unbiased_floatt result;
621
622 // now add/sub them
624
625 result.fraction=
629
630 // sign of result
631 std::size_t width=to_bitvector_type(result.fraction.type()).get_width();
633 typecast_exprt(result.fraction, signedbv_typet(width)));
634 result.fraction=
637 unsignedbv_typet(width));
638
640
641 // adjust the exponent for the fact that we added two bits to the fraction
642 result.exponent=
644 from_integer(2, signedbv_typet(spec.e+1)));
645
646 // NaN?
647 result.NaN=or_exprt(
648 and_exprt(and_exprt(unpacked1.infinity, unpacked2.infinity),
650 or_exprt(unpacked1.NaN, unpacked2.NaN));
651
652 // infinity?
653 result.infinity=and_exprt(
654 not_exprt(result.NaN),
655 or_exprt(unpacked1.infinity, unpacked2.infinity));
656
657 // zero?
658 // Note that:
659 // 1. The zero flag isn't used apart from in divide and
660 // is only set on unpack
661 // 2. Subnormals mean that addition or subtraction can't round to 0,
662 // thus we can perform this test now
663 // 3. The rules for sign are different for zero
664 result.zero=
665 and_exprt(
666 not_exprt(or_exprt(result.infinity, result.NaN)),
668 result.fraction,
669 from_integer(0, result.fraction.type())));
670
671 // sign
674
676 unpacked1.infinity, unpacked1.sign, unpacked2.sign);
677
678 #if 1
679 rounding_mode_bitst rounding_mode_bits(rm);
680
681 const if_exprt zero_sign(
682 rounding_mode_bits.round_to_minus_inf,
683 or_exprt(unpacked1.sign, unpacked2.sign),
684 and_exprt(unpacked1.sign, unpacked2.sign));
685
686 result.sign=if_exprt(
687 result.infinity,
689 if_exprt(result.zero,
690 zero_sign,
691 add_sub_sign));
692 #else
693 result.sign=if_exprt(
694 result.infinity,
697 #endif
698
699 return rounder(result, rm, spec);
700}
701
704 const exprt &dist,
706{
707 std::size_t nb_bits = address_bits(limit);
708 std::size_t dist_width=to_unsignedbv_type(dist.type()).get_width();
709
711 return dist;
712
717
719
720 return if_exprt(
723 unsignedbv_typet(nb_bits).largest_expr());
724}
725
727 const exprt &src1,
728 const exprt &src2,
729 const exprt &rm,
730 const ieee_float_spect &spec) const
731{
732 // unpack
735
736 // zero-extend the fractions (unpacked fraction has the hidden bit)
738 const exprt fraction1 =
740 const exprt fraction2 =
742
743 // multiply the fractions
744 unbiased_floatt result;
746
747 // extend exponents to account for overflow
748 // add two bits, as we do extra arithmetic on it later
752
754
755 // Adjust exponent; we are thowing in an extra fraction bit,
756 // it has been extended above.
757 result.exponent=
759
760 // new sign
761 result.sign=notequal_exprt(unpacked1.sign, unpacked2.sign);
762
763 // infinity?
764 result.infinity=or_exprt(unpacked1.infinity, unpacked2.infinity);
765
766 // NaN?
767 result.NaN = disjunction(
768 {isnan(src1, spec),
769 isnan(src2, spec),
770 // infinity * 0 is NaN!
771 and_exprt(unpacked1.zero, unpacked2.infinity),
772 and_exprt(unpacked2.zero, unpacked1.infinity)});
773
774 return rounder(result, rm, spec);
775}
776
778 const exprt &src1,
779 const exprt &src2,
780 const exprt &rm,
781 const ieee_float_spect &spec) const
782{
783 // unpack
786
787 std::size_t fraction_width=
788 to_unsignedbv_type(unpacked1.fraction.type()).get_width();
789 std::size_t div_width=fraction_width*2+1;
790
791 // pad fraction1 with zeros
793 unpacked1.fraction,
794 from_integer(0, unsignedbv_typet(div_width - fraction_width)),
796
797 // zero-extend fraction2 to match fraction1
798 const zero_extend_exprt fraction2{unpacked2.fraction, fraction1.type()};
799
800 // divide fractions
801 unbiased_floatt result;
802 exprt rem;
803
804 // the below should be merged somehow
807
808 // is there a remainder?
809 const notequal_exprt have_remainder(rem, from_integer(0, rem.type()));
810
811 // we throw this into the result, as least-significant bit,
812 // to get the right rounding decision
813 result.fraction=
816
817 // We will subtract the exponents;
818 // to account for overflow, we add a bit.
820 unpacked1.exponent, signedbv_typet(spec.e + 1));
822 unpacked2.exponent, signedbv_typet(spec.e + 1));
823
824 // subtract exponents
826
827 // adjust, as we have thown in extra fraction bits
828 result.exponent=plus_exprt(
830 from_integer(spec.f, added_exponent.type()));
831
832 // new sign
833 result.sign=notequal_exprt(unpacked1.sign, unpacked2.sign);
834
835 // Infinity? This happens when
836 // 1) dividing a non-nan/non-zero by zero, or
837 // 2) first operand is inf and second is non-nan and non-zero
838 // In particular, inf/0=inf.
839 result.infinity=
840 or_exprt(
843 unpacked2.zero)),
844 and_exprt(unpacked1.infinity,
846 not_exprt(unpacked2.zero))));
847
848 // NaN?
849 result.NaN=or_exprt(unpacked1.NaN,
852 and_exprt(unpacked1.infinity, unpacked2.infinity))));
853
854 // Division by infinity produces zero, unless we have NaN
855 const and_exprt force_zero(not_exprt(unpacked1.NaN), unpacked2.infinity);
856
857 result.fraction=
858 if_exprt(
860 from_integer(0, result.fraction.type()),
861 result.fraction);
862
863 return rounder(result, rm, spec);
864}
865
867 const exprt &multiply_lhs,
868 const exprt &multiply_rhs,
869 const exprt &addend,
870 const exprt &rm,
871 const ieee_float_spect &spec) const
872{
873 // Fused multiply-add: round(multiply_lhs * multiply_rhs + addend) with single
874 // rounding. Multiply at double width (exact), add at double width (exact),
875 // then round once.
876
880
881 const std::size_t frac_size = spec.f + 1;
882 const std::size_t prod_width = frac_size * 2;
884
885 // Exact product: multiply fractions at double width
886 const exprt fraction1 =
888 const exprt fraction2 =
891
892 const typet wide_exp_type = signedbv_typet(spec.e + 2);
897
899
900 // Align addend fraction to product width (pad on the right)
901 const std::size_t c_pad = prod_width - frac_size;
903 unpacked_add.fraction,
907
908 // Add product + c: align fractions by exponent difference
911
915
916 exprt distance =
919
920 // Pad with 3 guard bits
926
927 // Shift smaller fraction right, tracking sticky bit
933
934 // Extend for potential carry/borrow
938
939 // Add or subtract based on signs
945
946 // Handle negative result (from subtraction)
949 sum = if_exprt(
954
955 unbiased_floatt result;
956 result.fraction = sum;
957 result.exponent = plus_exprt(
959 from_integer(2, signedbv_typet(spec.e + 3)));
960
961 // Sign
964 result.sign = add_sub_sign;
965
966 // NaN
967 exprt prod_inf = or_exprt(unpacked_lhs.infinity, unpacked_rhs.infinity);
968 result.NaN = disjunction(
969 {isnan(multiply_lhs, spec),
970 isnan(multiply_rhs, spec),
971 isnan(addend, spec),
972 and_exprt(unpacked_lhs.zero, unpacked_rhs.infinity),
973 and_exprt(unpacked_rhs.zero, unpacked_lhs.infinity),
974 and_exprt(
977
978 // Infinity
979 result.infinity =
981
982 return rounder(result, rm, spec);
983}
984
986 const exprt &src1,
987 relt rel,
988 const exprt &src2,
989 const ieee_float_spect &spec)
990{
991 if(rel==relt::GT)
992 return relation(src2, relt::LT, src1, spec); // swapped
993 else if(rel==relt::GE)
994 return relation(src2, relt::LE, src1, spec); // swapped
995
996 INVARIANT(
997 rel == relt::EQ || rel == relt::LT || rel == relt::LE,
998 "relation should be equality, less-than, or less-or-equal");
999
1000 // special cases: -0 and 0 are equal
1001 const exprt is_zero1 = is_zero(src1);
1002 const exprt is_zero2 = is_zero(src2);
1004
1005 // NaN compares to nothing
1006 exprt isnan1=isnan(src1, spec);
1007 exprt isnan2=isnan(src2, spec);
1008 const or_exprt nan(isnan1, isnan2);
1009
1010 if(rel==relt::LT || rel==relt::LE)
1011 {
1013
1014 // signs different? trivial! Unless Zero.
1015
1017
1018 // as long as the signs match: compare like unsigned numbers
1019
1020 // this works due to the BIAS
1024 unsignedbv_typet(spec.width())),
1025 ID_lt,
1028 unsignedbv_typet(spec.width())));
1029
1030 // if both are negative (and not the same), need to turn around!
1033
1035
1036 if(rel==relt::LT)
1037 {
1039 // for the case of two negative numbers
1042 not_exprt(nan)}};
1043
1044 return std::move(and_bv);
1045 }
1046 else if(rel==relt::LE)
1047 {
1049
1050 return and_exprt(or_bv, not_exprt(nan));
1051 }
1052 else
1054 }
1055 else if(rel==relt::EQ)
1056 {
1058
1059 return and_exprt(
1061 not_exprt(nan));
1062 }
1063
1065 return false_exprt();
1066}
1067
1069 const exprt &src,
1070 const ieee_float_spect &spec)
1071{
1072 return and_exprt(
1073 exponent_all_ones(src, spec),
1074 fraction_all_zeros(src, spec));
1075}
1076
1078 const exprt &src,
1079 const ieee_float_spect &spec)
1080{
1081 return not_exprt(or_exprt(isinf(src, spec), isnan(src, spec)));
1082}
1083
1086 const exprt &src,
1087 const ieee_float_spect &spec)
1088{
1089 return extractbits_exprt(src, spec.f, unsignedbv_typet(spec.e));
1090}
1091
1094 const exprt &src,
1095 const ieee_float_spect &spec)
1096{
1097 return extractbits_exprt(src, 0, unsignedbv_typet(spec.f));
1098}
1099
1101 const exprt &src,
1102 const ieee_float_spect &spec)
1103{
1104 return and_exprt(exponent_all_ones(src, spec),
1105 not_exprt(fraction_all_zeros(src, spec)));
1106}
1107
1110 exprt &fraction,
1111 exprt &exponent)
1112{
1113 // n-log-n alignment shifter.
1114 // The worst-case shift is the number of fraction
1115 // bits minus one, in case the fraction is one exactly.
1116 std::size_t fraction_bits=to_unsignedbv_type(fraction.type()).get_width();
1117 std::size_t exponent_bits=to_signedbv_type(exponent.type()).get_width();
1119
1120 std::size_t depth = address_bits(fraction_bits - 1);
1121
1122 exponent = typecast_exprt(
1123 exponent, signedbv_typet(std::max(depth, exponent_bits + 1)));
1124
1125 exprt exponent_delta=from_integer(0, exponent.type());
1126
1127 for(int d=depth-1; d>=0; d--)
1128 {
1129 unsigned distance=(1<<d);
1130 INVARIANT(
1131 fraction_bits > distance,
1132 "distance must be within the range of fraction bits");
1133
1134 // check if first 'distance'-many bits are zeros
1135 const extractbits_exprt prefix(
1136 fraction, fraction_bits - distance, unsignedbv_typet(distance));
1137 const equal_exprt prefix_is_zero(prefix, from_integer(0, prefix.type()));
1138
1139 // If so, shift the zeros out left by 'distance'.
1140 // Otherwise, leave as is.
1141 const shl_exprt shifted(fraction, distance);
1142
1143 fraction=
1144 if_exprt(prefix_is_zero, shifted, fraction);
1145
1146 // add corresponding weight to exponent
1147 INVARIANT(
1148 d < (signed int)exponent_bits,
1149 "depth must be smaller than exponent bits");
1150
1154 }
1155
1156 exponent=minus_exprt(exponent, exponent_delta);
1157}
1158
1161 exprt &fraction,
1162 exprt &exponent,
1163 const ieee_float_spect &spec)
1164{
1165 mp_integer bias=spec.bias();
1166
1167 // Is the exponent strictly less than -bias+1, i.e., exponent<-bias+1?
1168 // This is transformed to distance=(-bias+1)-exponent
1169 // i.e., distance>0
1170 // Note that 1-bias is the exponent represented by 0...01,
1171 // i.e. the exponent of the smallest normal number and thus the 'base'
1172 // exponent for subnormal numbers.
1173
1174 std::size_t exponent_bits=to_signedbv_type(exponent.type()).get_width();
1175 PRECONDITION(exponent_bits >= spec.e);
1176
1177#if 1
1178 // Need to sign extend to avoid overflow. Note that this is a
1179 // relatively rare problem as the value needs to be close to the top
1180 // of the exponent range and then range must not have been
1181 // previously extended as add, multiply, etc. do. This is primarily
1182 // to handle casting down from larger ranges.
1183 exponent=typecast_exprt(exponent, signedbv_typet(exponent_bits+1));
1184#endif
1185
1186 const minus_exprt distance(
1187 from_integer(-bias + 1, exponent.type()), exponent);
1188
1189 // use sign bit
1190 const and_exprt denormal(
1191 not_exprt(sign_exprt(distance)),
1192 notequal_exprt(distance, from_integer(0, distance.type())));
1193
1194#if 1
1195 // Care must be taken to not loose information required for the
1196 // guard and sticky bits. +3 is for the hidden, guard and sticky bits.
1197 std::size_t fraction_bits=to_unsignedbv_type(fraction.type()).get_width();
1198
1199 if(fraction_bits < spec.f+3)
1200 {
1201 // Add zeros at the LSB end for the guard bit to shift into
1202 fraction=
1204 fraction, unsignedbv_typet(spec.f + 3 - fraction_bits).zero_expr(),
1205 unsignedbv_typet(spec.f+3));
1206 }
1207
1208 exprt denormalisedFraction = fraction;
1209
1212 sticky_right_shift(fraction, distance, sticky_bit);
1213
1217
1218 fraction=
1219 if_exprt(
1220 denormal,
1222 fraction);
1223
1224#else
1225 fraction=
1226 if_exprt(
1227 denormal,
1228 lshr_exprt(fraction, distance),
1229 fraction);
1230#endif
1231
1232 exponent=
1234 from_integer(-bias, exponent.type()),
1235 exponent);
1236}
1237
1239 const unbiased_floatt &src,
1240 const exprt &rm,
1241 const ieee_float_spect &spec) const
1242{
1243 // incoming: some fraction (with explicit 1),
1244 // some exponent without bias
1245 // outgoing: rounded, with right size, with hidden bit, bias
1246
1249
1250 {
1251 std::size_t exponent_bits = std::max(address_bits(spec.f), spec.e) + 1;
1252
1253 // before normalization, make sure exponent is large enough
1254 if(to_signedbv_type(aligned_exponent.type()).get_width()<exponent_bits)
1255 {
1256 // sign extend
1259 }
1260 }
1261
1262 // align it!
1265
1266 unbiased_floatt result;
1269 result.sign=src.sign;
1270 result.NaN=src.NaN;
1271 result.infinity=src.infinity;
1272
1273 rounding_mode_bitst rounding_mode_bits(rm);
1274 round_fraction(result, rounding_mode_bits, spec);
1275 round_exponent(result, rounding_mode_bits, spec);
1276
1277 return pack(bias(result, spec), spec);
1278}
1279
1282 const std::size_t dest_bits,
1283 const exprt sign,
1284 const exprt &fraction,
1285 const rounding_mode_bitst &rounding_mode_bits)
1286{
1287 std::size_t fraction_bits=
1288 to_unsignedbv_type(fraction.type()).get_width();
1289
1291
1292 // we have too many fraction bits
1294
1295 // more than two extra bits are superflus, and are
1296 // turned into a sticky bit
1297
1299
1300 if(extra_bits>=2)
1301 {
1302 // We keep most-significant bits, and thus the tail is made
1303 // of least-significant bits.
1304 const extractbits_exprt tail(
1305 fraction, 0, unsignedbv_typet(extra_bits - 2 + 1));
1306 sticky_bit=notequal_exprt(tail, from_integer(0, tail.type()));
1307 }
1308
1309 // the rounding bit is the last extra bit
1310 INVARIANT(
1311 extra_bits >= 1, "the extra bits contain at least the rounding bit");
1312 const extractbit_exprt rounding_bit(fraction, extra_bits - 1);
1313
1314 // we get one bit of the fraction for some rounding decisions
1316
1317 // round-to-nearest (ties to even)
1318 const and_exprt round_to_even(
1320
1321 // round up
1322 const and_exprt round_to_plus_inf(
1324
1325 // round down
1326 const and_exprt round_to_minus_inf(sign, or_exprt(rounding_bit, sticky_bit));
1327
1328 // round to zero
1329 false_exprt round_to_zero;
1330
1331 // round-to-nearest (ties to away)
1332 const auto round_to_away = rounding_bit;
1333
1334 // now select appropriate one
1335 // clang-format off
1336 return if_exprt(rounding_mode_bits.round_to_even, round_to_even,
1337 if_exprt(rounding_mode_bits.round_to_plus_inf, round_to_plus_inf,
1338 if_exprt(rounding_mode_bits.round_to_minus_inf, round_to_minus_inf,
1339 if_exprt(rounding_mode_bits.round_to_zero, round_to_zero,
1340 if_exprt(rounding_mode_bits.round_to_away, round_to_away,
1341 false_exprt()))))); // otherwise zero
1342 // clang-format off
1343}
1344
1346 unbiased_floatt &result,
1347 const rounding_mode_bitst &rounding_mode_bits,
1348 const ieee_float_spect &spec)
1349{
1350 std::size_t fraction_size=spec.f+1;
1351 std::size_t result_fraction_size=
1352 to_unsignedbv_type(result.fraction.type()).get_width();
1353
1354 // do we need to enlarge the fraction?
1356 {
1357 // pad with zeros at bottom
1359
1361 result.fraction,
1362 unsignedbv_typet(padding).zero_expr(),
1364 }
1365 else if(result_fraction_size==fraction_size) // it stays
1366 {
1367 // do nothing
1368 }
1369 else // fraction gets smaller -- rounding
1370 {
1372 INVARIANT(
1373 extra_bits >= 1, "the extra bits include at least the rounding bit");
1374
1375 // this computes the rounding decision
1377 fraction_size, result.sign, result.fraction, rounding_mode_bits);
1378
1379 // chop off all the extra bits
1380 result.fraction = extractbits_exprt(
1382
1383#if 0
1384 // *** does not catch when the overflow goes subnormal -> normal ***
1385 // incrementing the fraction might result in an overflow
1386 result.fraction=
1387 bv_utils.zero_extension(result.fraction, result.fraction.size()+1);
1388
1389 result.fraction=bv_utils.incrementer(result.fraction, increment);
1390
1391 exprt overflow=result.fraction.back();
1392
1393 // In case of an overflow, the exponent has to be incremented.
1394 // "Post normalization" is then required.
1395 result.exponent=
1396 bv_utils.incrementer(result.exponent, overflow);
1397
1398 // post normalization of the fraction
1399 exprt integer_part1=result.fraction.back();
1400 exprt integer_part0=result.fraction[result.fraction.size()-2];
1402
1403 result.fraction.resize(result.fraction.size()-1);
1404 result.fraction.back()=new_integer_part;
1405
1406#else
1407 // When incrementing due to rounding there are two edge
1408 // cases we need to be aware of:
1409 // 1. If the number is normal, the increment can overflow.
1410 // In this case we need to increment the exponent and
1411 // set the MSB of the fraction to 1.
1412 // 2. If the number is the largest subnormal, the increment
1413 // can change the MSB making it normal. Thus the exponent
1414 // must be incremented but the fraction will be OK.
1416
1417 // increment if 'increment' is true
1418 result.fraction=
1419 plus_exprt(result.fraction,
1420 typecast_exprt(increment, result.fraction.type()));
1421
1422 // Normal overflow when old MSB == 1 and new MSB == 0
1425
1426 // Subnormal to normal transition when old MSB == 0 and new MSB == 1
1428
1429 // In case of an overflow or subnormal to normal conversion,
1430 // the exponent has to be incremented.
1431 result.exponent=
1432 plus_exprt(
1433 result.exponent,
1434 if_exprt(
1436 from_integer(1, result.exponent.type()),
1437 from_integer(0, result.exponent.type())));
1438
1439 // post normalization of the fraction
1440 // In the case of overflow, set the MSB to 1
1441 // The subnormal case will have (only) the MSB set to 1
1442 result.fraction=bitor_exprt(
1443 result.fraction,
1445 from_integer(1<<(fraction_size-1), result.fraction.type()),
1446 from_integer(0, result.fraction.type())));
1447#endif
1448 }
1449}
1450
1452 unbiased_floatt &result,
1453 const rounding_mode_bitst &rounding_mode_bits,
1454 const ieee_float_spect &spec)
1455{
1456 std::size_t result_exponent_size=
1457 to_signedbv_type(result.exponent.type()).get_width();
1458
1460
1461 // do we need to enlarge the exponent?
1462 if(result_exponent_size == spec.e) // it stays
1463 {
1464 // do nothing
1465 }
1466 else // exponent gets smaller -- chop off top bits
1467 {
1469 result.exponent =
1470 extractbits_exprt(result.exponent, 0, signedbv_typet(spec.e));
1471
1472 // max_exponent is the maximum representable
1473 // i.e. 1 higher than the maximum possible for a normal number
1474 exprt max_exponent=
1476 spec.max_exponent()-spec.bias(), old_exponent.type());
1477
1478 // the exponent is garbage if the fractional is zero
1479
1482 notequal_exprt(result.fraction, from_integer(0, result.fraction.type())));
1483
1484#if 1
1485 // Directed rounding modes round overflow to the maximum normal
1486 // depending on the particular mode and the sign
1488 rounding_mode_bits.round_to_even,
1489 or_exprt(
1490 and_exprt(rounding_mode_bits.round_to_plus_inf, not_exprt(result.sign)),
1491 and_exprt(rounding_mode_bits.round_to_minus_inf, result.sign)));
1492
1494
1497 spec.max_exponent()-(spec.bias() + 1), result.exponent.type());
1498
1499 result.exponent=
1501
1502 result.fraction=
1504 to_unsignedbv_type(result.fraction.type()).largest_expr(),
1505 result.fraction);
1506
1507 result.infinity=or_exprt(result.infinity,
1510#else
1512#endif
1513 }
1514}
1515
1518 const unbiased_floatt &src,
1519 const ieee_float_spect &spec)
1520{
1521 biased_floatt result;
1522
1523 result.sign=src.sign;
1524 result.NaN=src.NaN;
1525 result.infinity=src.infinity;
1526
1527 // we need to bias the new exponent
1528 result.exponent=add_bias(src.exponent, spec);
1529
1530 // strip off the hidden bit
1532 to_unsignedbv_type(src.fraction.type()).get_width() == spec.f + 1);
1533
1534 const extractbit_exprt hidden_bit(src.fraction, spec.f);
1536
1537 result.fraction =
1539
1540 // make exponent zero if its denormal
1541 // (includes zero)
1542 result.exponent=
1544 result.exponent);
1545
1546 return result;
1547}
1548
1550 const exprt &src,
1551 const ieee_float_spect &spec)
1552{
1553 typet t=unsignedbv_typet(spec.e);
1554 return plus_exprt(
1555 typecast_exprt(src, t),
1556 from_integer(spec.bias(), t));
1557}
1558
1560 const exprt &src,
1561 const ieee_float_spect &spec)
1562{
1563 typet t=signedbv_typet(spec.e);
1564 return minus_exprt(
1565 typecast_exprt(src, t),
1566 from_integer(spec.bias(), t));
1567}
1568
1570 const exprt &src,
1571 const ieee_float_spect &spec)
1572{
1573 unbiased_floatt result;
1574
1575 result.sign=sign_bit(src);
1576
1577 result.fraction=get_fraction(src, spec);
1578
1579 // add hidden bit
1580 exprt hidden_bit=isnormal(src, spec);
1581 result.fraction=
1583 unsignedbv_typet(spec.f+1));
1584
1585 result.exponent=get_exponent(src, spec);
1586
1587 // unbias the exponent
1589
1590 result.exponent=
1592 from_integer(-spec.bias()+1, signedbv_typet(spec.e)),
1593 sub_bias(result.exponent, spec));
1594
1595 result.infinity=isinf(src, spec);
1596 result.zero = is_zero(src);
1597 result.NaN=isnan(src, spec);
1598
1599 return result;
1600}
1601
1603 const biased_floatt &src,
1604 const ieee_float_spect &spec)
1605{
1606 PRECONDITION(to_unsignedbv_type(src.fraction.type()).get_width() == spec.f);
1607 PRECONDITION(to_unsignedbv_type(src.exponent.type()).get_width() == spec.e);
1608
1609 // do sign -- we make this 'false' for NaN
1610 const if_exprt sign_bit(src.NaN, false_exprt(), src.sign);
1611
1612 // the fraction is zero in case of infinity,
1613 // and one in case of NaN
1614 const if_exprt fraction(
1615 src.NaN,
1616 from_integer(1, src.fraction.type()),
1617 if_exprt(src.infinity, from_integer(0, src.fraction.type()), src.fraction));
1618
1619 const or_exprt infinity_or_NaN(src.NaN, src.infinity);
1620
1621 // do exponent
1622 const if_exprt exponent(
1624
1625 // stitch all three together
1626 return typecast_exprt(
1628 {std::move(sign_bit), std::move(exponent), std::move(fraction)},
1629 bv_typet(spec.f + spec.e + 1)),
1630 spec.to_type());
1631}
1632
1634 const exprt &op,
1635 const exprt &dist,
1636 exprt &sticky)
1637{
1638 std::size_t d=1, width=to_unsignedbv_type(op.type()).get_width();
1639 exprt result=op;
1641
1642 std::size_t dist_width=to_bitvector_type(dist.type()).get_width();
1643
1644 for(std::size_t stage=0; stage<dist_width; stage++)
1645 {
1646 const lshr_exprt tmp(result, d);
1647
1649
1650 if(d<=width)
1652 else
1653 lost_bits=result;
1654
1656
1657 sticky=
1658 or_exprt(
1659 and_exprt(
1660 dist_bit,
1662 sticky);
1663
1664 result=if_exprt(dist_bit, tmp, result);
1665
1666 d=d<<1;
1667 }
1668
1669 return result;
1670}
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
std::size_t address_bits(const mp_integer &size)
ceil(log2(size))
irep_idt integer2bvrep(const mp_integer &src, std::size_t width)
convert an integer to bit-vector representation with given width This uses two's complement for negat...
mp_integer power(const mp_integer &base, const mp_integer &exponent)
A multi-precision implementation of the power operator.
API to expression classes for bitvectors.
Pre-defined bitvector types.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
Absolute value.
Definition std_expr.h:440
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:566
Boolean AND All operands must be boolean, and the result is always boolean.
Definition std_expr.h:2043
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition std_expr.h:784
Bit-wise AND Any number of operands that is greater or equal one.
Bit-wise OR Any number of operands that is greater or equal one.
Base class of fixed-width bit-vector types.
std::size_t get_width() const
Bit-wise XOR Any number of operands that is greater or equal one.
Fixed-width bit-vector without numerical interpretation.
Concatenation of bit-vector operands.
A constant literal expression.
Definition std_expr.h:3007
Division.
Definition std_expr.h:1152
Equality.
Definition std_expr.h:1339
Base class for all expressions.
Definition expr.h:57
bool is_boolean() const
Return whether the expression represents a Boolean.
Definition expr.h:229
typet & type()
Return the type of the expression.
Definition expr.h:85
Extracts a single bit of a bit-vector operand.
Extracts a sub-range of a bit-vector operand.
The Boolean constant false.
Definition std_expr.h:3135
static unbiased_floatt unpack(const exprt &, const ieee_float_spect &)
static void normalization_shift(exprt &fraction, exprt &exponent)
normalize fraction/exponent pair returns 'zero' if fraction is zero
static exprt get_fraction(const exprt &, const ieee_float_spect &)
Gets the fraction without hidden bit in a floating-point bit-vector src.
static exprt sub_bias(const exprt &exponent, const ieee_float_spect &)
static exprt exponent_all_ones(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:260
static exprt to_integer(const exprt &src, std::size_t dest_width, bool is_signed, const exprt &rm, const ieee_float_spect &)
Definition float_bv.cpp:377
exprt from_unsigned_integer(const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:337
static exprt isfinite(const exprt &, const ieee_float_spect &)
static exprt isnormal(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:528
exprt from_signed_integer(const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:313
exprt add_sub(bool subtract, const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:557
static exprt is_zero(const exprt &)
Definition float_bv.cpp:244
static exprt abs(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:202
static void round_fraction(unbiased_floatt &result, const rounding_mode_bitst &, const ieee_float_spect &)
static exprt fraction_rounding_decision(const std::size_t dest_bits, const exprt sign, const exprt &fraction, const rounding_mode_bitst &)
rounding decision for fraction using sticky bit
exprt conversion(const exprt &src, const exprt &rm, const ieee_float_spect &src_spec, const ieee_float_spect &dest_spec) const
Definition float_bv.cpp:454
static exprt isnan(const exprt &, const ieee_float_spect &)
static biased_floatt bias(const unbiased_floatt &, const ieee_float_spect &)
takes an unbiased float, and applies the bias
static exprt get_exponent(const exprt &, const ieee_float_spect &)
Gets the unbiased exponent in a floating-point bit-vector.
static void denormalization_shift(exprt &fraction, exprt &exponent, const ieee_float_spect &)
make sure exponent is not too small; the exponent is unbiased
static exprt add_bias(const exprt &exponent, const ieee_float_spect &)
static exprt sticky_right_shift(const exprt &op, const exprt &dist, exprt &sticky)
exprt rounder(const unbiased_floatt &, const exprt &rm, const ieee_float_spect &) const
exprt fma(const exprt &multiply_lhs, const exprt &multiply_rhs, const exprt &addend, const exprt &rm, const ieee_float_spect &) const
Fused multiply-add: round(multiply_lhs * multiply_rhs + addend) with a single rounding step.
Definition float_bv.cpp:866
static exprt subtract_exponents(const unbiased_floatt &src1, const unbiased_floatt &src2)
Subtracts the exponents.
Definition float_bv.cpp:538
exprt div(const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:777
exprt convert(const exprt &) const
Definition float_bv.cpp:19
static ieee_float_spect get_spec(const exprt &)
Definition float_bv.cpp:196
static exprt to_unsigned_integer(const exprt &src, std::size_t dest_width, const exprt &rm, const ieee_float_spect &)
Definition float_bv.cpp:368
static exprt negation(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:212
static exprt relation(const exprt &, relt rel, const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:985
static exprt isinf(const exprt &, const ieee_float_spect &)
static exprt sign_bit(const exprt &)
Definition float_bv.cpp:306
exprt mul(const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:726
static exprt fraction_all_zeros(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:278
static exprt exponent_all_zeros(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:269
static exprt is_equal(const exprt &, const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:222
static exprt to_signed_integer(const exprt &src, std::size_t dest_width, const exprt &rm, const ieee_float_spect &)
Definition float_bv.cpp:359
static exprt limit_distance(const exprt &dist, mp_integer limit)
Limits the shift distance.
Definition float_bv.cpp:703
static exprt pack(const biased_floatt &, const ieee_float_spect &)
static void round_exponent(unbiased_floatt &result, const rounding_mode_bitst &, const ieee_float_spect &)
Fixed-width bit-vector with IEEE floating-point interpretation.
class floatbv_typet to_type() const
mp_integer bias() const
mp_integer max_exponent() const
std::size_t f
Definition ieee_float.h:26
std::size_t width() const
Definition ieee_float.h:50
std::size_t e
Definition ieee_float.h:26
An IEEE 754 floating-point value, including specificiation.
Definition ieee_float.h:117
The trinary if-then-else operator.
Definition std_expr.h:2426
constant_exprt zero_expr() const
Return an expression representing the zero value of this type.
const irep_idt & id() const
Definition irep.h:388
Logical right shift.
Binary minus.
Definition std_expr.h:1065
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Definition std_expr.h:1216
Binary multiplication Associativity is not specified.
Definition std_expr.h:1104
The NIL expression.
Definition std_expr.h:3144
Boolean negation.
Definition std_expr.h:2388
Disequality.
Definition std_expr.h:1393
Boolean OR All operands must be boolean, and the result is always boolean.
Definition std_expr.h:2193
The plus expression Associativity is not specified.
Definition std_expr.h:1006
Left shift.
Sign of an expression Predicate is true if _op is negative, false otherwise.
Definition std_expr.h:612
Fixed-width bit-vector with two's complement interpretation.
Semantic type conversion.
Definition std_expr.h:1995
The type of an expression, extends irept.
Definition type.h:29
The unary minus expression.
Definition std_expr.h:477
Fixed-width bit-vector with unsigned binary interpretation.
zero extension The operand is converted to the given type by either a) truncating if the new type is ...
API to expression classes for floating-point arithmetic.
const ieee_float_op_exprt & to_ieee_float_op_expr(const exprt &expr)
Cast an exprt to an ieee_float_op_exprt.
const floatbv_fma_exprt & to_floatbv_fma_expr(const exprt &expr)
const ieee_float_notequal_exprt & to_ieee_float_notequal_expr(const exprt &expr)
Cast an exprt to an ieee_float_notequal_exprt.
const ieee_float_equal_exprt & to_ieee_float_equal_expr(const exprt &expr)
Cast an exprt to an ieee_float_equal_exprt.
const floatbv_typecast_exprt & to_floatbv_typecast_expr(const exprt &expr)
Cast an exprt to a floatbv_typecast_exprt.
double nan(const char *str)
Definition math.c:626
BigInt mp_integer
Definition smt_terms.h:17
#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
exprt disjunction(const exprt::operandst &op)
1) generates a disjunction for two or more operands 2) for one operand, returns the operand 3) return...
Definition std_expr.cpp:240
API to expression classes.
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
Definition std_expr.h:828
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition std_expr.h:2024
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition std_expr.h:424
const abs_exprt & to_abs_expr(const exprt &expr)
Cast an exprt to a abs_exprt.
Definition std_expr.h:459
const unary_minus_exprt & to_unary_minus_expr(const exprt &expr)
Cast an exprt to a unary_minus_exprt.
Definition std_expr.h:502
void get(const exprt &rm)
Definition float_bv.cpp:288
bool is_signed(const typet &t)
Convenience function – is the type signed?
Definition util.cpp:45