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 const unbiased_floatt unpacked=unpack(src, spec);
385
386 rounding_mode_bitst rounding_mode_bits(rm);
387
388 // Right now hard-wired to round-to-zero, which is
389 // the usual case in ANSI-C.
390
391 // if the exponent is positive, shift right
392 exprt offset=from_integer(spec.f, signedbv_typet(spec.e));
393 const minus_exprt distance(offset, unpacked.exponent);
394 const lshr_exprt shift_result(unpacked.fraction, distance);
395
396 // if the exponent is negative, we have zero anyways
397 exprt result=shift_result;
398 const sign_exprt exponent_sign(unpacked.exponent);
399
400 result=
401 if_exprt(exponent_sign, from_integer(0, result.type()), result);
402
403 // chop out the right number of bits from the result
404 typet result_type=
406 static_cast<typet>(unsignedbv_typet(dest_width));
407
408 result=typecast_exprt(result, result_type);
409
410 // if signed, apply sign.
411 if(is_signed)
412 {
413 result=if_exprt(
414 unpacked.sign, unary_minus_exprt(result), result);
415 }
416 else
417 {
418 // It's unclear what the behaviour for negative floats
419 // to integer shall be.
420 }
421
422 return result;
423}
424
426 const exprt &src,
427 const exprt &rm,
429 const ieee_float_spect &dest_spec) const
430{
431 // Catch the special case in which we extend,
432 // e.g. single to double.
433 // In this case, rounding can be avoided,
434 // but a denormal number may be come normal.
435 // Be careful to exclude the difficult case
436 // when denormalised numbers in the old format
437 // can be converted to denormalised numbers in the
438 // new format. Note that this is rare and will only
439 // happen with very non-standard formats.
440
441 int sourceSmallestNormalExponent = -((1 << (src_spec.e - 1)) - 1);
444
445 // Using the fact that f doesn't include the hidden bit
446
447 int destSmallestNormalExponent = -((1 << (dest_spec.e - 1)) - 1);
448
449 if(dest_spec.e>=src_spec.e &&
450 dest_spec.f>=src_spec.f &&
452 {
454 unbiased_floatt result;
455
456 // the fraction gets zero-padded
457 std::size_t padding=dest_spec.f-src_spec.f;
458 result.fraction=
460 unpacked_src.fraction,
463
464 // the exponent gets sign-extended
465 INVARIANT(
466 unpacked_src.exponent.type().id() == ID_signedbv,
467 "the exponent needs to have a signed type");
468 result.exponent=
470
471 // if the number was denormal and is normal in the new format,
472 // normalise it!
473 if(dest_spec.e > src_spec.e)
474 {
475 normalization_shift(result.fraction, result.exponent);
476 // normalization_shift unconditionally extends the exponent size to avoid
477 // arithmetic overflow, but this cannot have happened here as the exponent
478 // had already been extended to dest_spec's size
479 result.exponent =
481 }
482
483 // the flags get copied
484 result.sign=unpacked_src.sign;
485 result.NaN=unpacked_src.NaN;
486 result.infinity=unpacked_src.infinity;
487
488 // no rounding needed!
489 return pack(bias(result, dest_spec), dest_spec);
490 }
491 else
492 {
493 // we actually need to round
494 unbiased_floatt result=unpack(src, src_spec);
495 return rounder(result, rm, dest_spec);
496 }
497}
498
500 const exprt &src,
501 const ieee_float_spect &spec)
502{
503 return and_exprt(
504 not_exprt(exponent_all_zeros(src, spec)),
505 not_exprt(exponent_all_ones(src, spec)));
506}
507
510 const unbiased_floatt &src1,
511 const unbiased_floatt &src2)
512{
513 // extend both by one bit
514 std::size_t old_width1=to_signedbv_type(src1.exponent.type()).get_width();
515 std::size_t old_width2=to_signedbv_type(src2.exponent.type()).get_width();
517
519 src1.exponent, signedbv_typet(old_width1 + 1));
520
522 src2.exponent, signedbv_typet(old_width2 + 1));
523
524 // compute shift distance (here is the subtraction)
526}
527
529 bool subtract,
530 const exprt &op0,
531 const exprt &op1,
532 const exprt &rm,
533 const ieee_float_spect &spec) const
534{
537
538 // subtract?
539 if(subtract)
540 unpacked2.sign=not_exprt(unpacked2.sign);
541
542 // figure out which operand has the bigger exponent
545
547 if_exprt(src2_bigger, unpacked2.exponent, unpacked1.exponent);
548
549 // swap fractions as needed
550 const exprt new_fraction1=
551 if_exprt(src2_bigger, unpacked2.fraction, unpacked1.fraction);
552
553 const exprt new_fraction2=
554 if_exprt(src2_bigger, unpacked1.fraction, unpacked2.fraction);
555
556 // compute distance
557 const exprt distance=
559
560 // limit the distance: shifting more than f+3 bits is unnecessary
561 const exprt limited_dist=limit_distance(distance, spec.f+3);
562
563 // pad fractions with 3 zeros from below
565 // add 4 to spec.f because unpacked new_fraction has the hidden bit
570
571 // shift new_fraction2
576
577 // sticky bit: 'or' of the bits lost by the right-shift
581 from_integer(0, unsignedbv_typet(spec.f + 3)),
583 fraction2_shifted.type()));
584
585 // need to have two extra fraction bits for addition and rounding
586 const exprt fraction1_ext=
588 const exprt fraction2_ext=
590
591 unbiased_floatt result;
592
593 // now add/sub them
595
596 result.fraction=
600
601 // sign of result
602 std::size_t width=to_bitvector_type(result.fraction.type()).get_width();
604 typecast_exprt(result.fraction, signedbv_typet(width)));
605 result.fraction=
608 unsignedbv_typet(width));
609
611
612 // adjust the exponent for the fact that we added two bits to the fraction
613 result.exponent=
615 from_integer(2, signedbv_typet(spec.e+1)));
616
617 // NaN?
618 result.NaN=or_exprt(
619 and_exprt(and_exprt(unpacked1.infinity, unpacked2.infinity),
621 or_exprt(unpacked1.NaN, unpacked2.NaN));
622
623 // infinity?
624 result.infinity=and_exprt(
625 not_exprt(result.NaN),
626 or_exprt(unpacked1.infinity, unpacked2.infinity));
627
628 // zero?
629 // Note that:
630 // 1. The zero flag isn't used apart from in divide and
631 // is only set on unpack
632 // 2. Subnormals mean that addition or subtraction can't round to 0,
633 // thus we can perform this test now
634 // 3. The rules for sign are different for zero
635 result.zero=
636 and_exprt(
637 not_exprt(or_exprt(result.infinity, result.NaN)),
639 result.fraction,
640 from_integer(0, result.fraction.type())));
641
642 // sign
645
647 unpacked1.infinity, unpacked1.sign, unpacked2.sign);
648
649 #if 1
650 rounding_mode_bitst rounding_mode_bits(rm);
651
652 const if_exprt zero_sign(
653 rounding_mode_bits.round_to_minus_inf,
654 or_exprt(unpacked1.sign, unpacked2.sign),
655 and_exprt(unpacked1.sign, unpacked2.sign));
656
657 result.sign=if_exprt(
658 result.infinity,
660 if_exprt(result.zero,
661 zero_sign,
662 add_sub_sign));
663 #else
664 result.sign=if_exprt(
665 result.infinity,
668 #endif
669
670 return rounder(result, rm, spec);
671}
672
675 const exprt &dist,
677{
678 std::size_t nb_bits = address_bits(limit);
679 std::size_t dist_width=to_unsignedbv_type(dist.type()).get_width();
680
682 return dist;
683
688
690
691 return if_exprt(
694 unsignedbv_typet(nb_bits).largest_expr());
695}
696
698 const exprt &src1,
699 const exprt &src2,
700 const exprt &rm,
701 const ieee_float_spect &spec) const
702{
703 // unpack
706
707 // zero-extend the fractions (unpacked fraction has the hidden bit)
709 const exprt fraction1 =
711 const exprt fraction2 =
713
714 // multiply the fractions
715 unbiased_floatt result;
717
718 // extend exponents to account for overflow
719 // add two bits, as we do extra arithmetic on it later
723
725
726 // Adjust exponent; we are thowing in an extra fraction bit,
727 // it has been extended above.
728 result.exponent=
730
731 // new sign
732 result.sign=notequal_exprt(unpacked1.sign, unpacked2.sign);
733
734 // infinity?
735 result.infinity=or_exprt(unpacked1.infinity, unpacked2.infinity);
736
737 // NaN?
738 result.NaN = disjunction(
739 {isnan(src1, spec),
740 isnan(src2, spec),
741 // infinity * 0 is NaN!
742 and_exprt(unpacked1.zero, unpacked2.infinity),
743 and_exprt(unpacked2.zero, unpacked1.infinity)});
744
745 return rounder(result, rm, spec);
746}
747
749 const exprt &src1,
750 const exprt &src2,
751 const exprt &rm,
752 const ieee_float_spect &spec) const
753{
754 // unpack
757
758 std::size_t fraction_width=
759 to_unsignedbv_type(unpacked1.fraction.type()).get_width();
760 std::size_t div_width=fraction_width*2+1;
761
762 // pad fraction1 with zeros
764 unpacked1.fraction,
765 from_integer(0, unsignedbv_typet(div_width - fraction_width)),
767
768 // zero-extend fraction2 to match fraction1
769 const zero_extend_exprt fraction2{unpacked2.fraction, fraction1.type()};
770
771 // divide fractions
772 unbiased_floatt result;
773 exprt rem;
774
775 // the below should be merged somehow
778
779 // is there a remainder?
780 const notequal_exprt have_remainder(rem, from_integer(0, rem.type()));
781
782 // we throw this into the result, as least-significant bit,
783 // to get the right rounding decision
784 result.fraction=
787
788 // We will subtract the exponents;
789 // to account for overflow, we add a bit.
791 unpacked1.exponent, signedbv_typet(spec.e + 1));
793 unpacked2.exponent, signedbv_typet(spec.e + 1));
794
795 // subtract exponents
797
798 // adjust, as we have thown in extra fraction bits
799 result.exponent=plus_exprt(
801 from_integer(spec.f, added_exponent.type()));
802
803 // new sign
804 result.sign=notequal_exprt(unpacked1.sign, unpacked2.sign);
805
806 // Infinity? This happens when
807 // 1) dividing a non-nan/non-zero by zero, or
808 // 2) first operand is inf and second is non-nan and non-zero
809 // In particular, inf/0=inf.
810 result.infinity=
811 or_exprt(
814 unpacked2.zero)),
815 and_exprt(unpacked1.infinity,
817 not_exprt(unpacked2.zero))));
818
819 // NaN?
820 result.NaN=or_exprt(unpacked1.NaN,
823 and_exprt(unpacked1.infinity, unpacked2.infinity))));
824
825 // Division by infinity produces zero, unless we have NaN
826 const and_exprt force_zero(not_exprt(unpacked1.NaN), unpacked2.infinity);
827
828 result.fraction=
829 if_exprt(
831 from_integer(0, result.fraction.type()),
832 result.fraction);
833
834 return rounder(result, rm, spec);
835}
836
838 const exprt &multiply_lhs,
839 const exprt &multiply_rhs,
840 const exprt &addend,
841 const exprt &rm,
842 const ieee_float_spect &spec) const
843{
844 // Fused multiply-add: round(multiply_lhs * multiply_rhs + addend) with single
845 // rounding. Multiply at double width (exact), add at double width (exact),
846 // then round once.
847
851
852 const std::size_t frac_size = spec.f + 1;
853 const std::size_t prod_width = frac_size * 2;
855
856 // Exact product: multiply fractions at double width
857 const exprt fraction1 =
859 const exprt fraction2 =
862
863 const typet wide_exp_type = signedbv_typet(spec.e + 2);
868
870
871 // Align addend fraction to product width (pad on the right)
872 const std::size_t c_pad = prod_width - frac_size;
874 unpacked_add.fraction,
878
879 // Add product + c: align fractions by exponent difference
882
886
887 exprt distance =
890
891 // Pad with 3 guard bits
897
898 // Shift smaller fraction right, tracking sticky bit
904
905 // Extend for potential carry/borrow
909
910 // Add or subtract based on signs
916
917 // Handle negative result (from subtraction)
920 sum = if_exprt(
925
926 unbiased_floatt result;
927 result.fraction = sum;
928 result.exponent = plus_exprt(
930 from_integer(2, signedbv_typet(spec.e + 3)));
931
932 // Sign
935 result.sign = add_sub_sign;
936
937 // NaN
938 exprt prod_inf = or_exprt(unpacked_lhs.infinity, unpacked_rhs.infinity);
939 result.NaN = disjunction(
940 {isnan(multiply_lhs, spec),
941 isnan(multiply_rhs, spec),
942 isnan(addend, spec),
943 and_exprt(unpacked_lhs.zero, unpacked_rhs.infinity),
944 and_exprt(unpacked_rhs.zero, unpacked_lhs.infinity),
945 and_exprt(
948
949 // Infinity
950 result.infinity =
952
953 return rounder(result, rm, spec);
954}
955
957 const exprt &src1,
958 relt rel,
959 const exprt &src2,
960 const ieee_float_spect &spec)
961{
962 if(rel==relt::GT)
963 return relation(src2, relt::LT, src1, spec); // swapped
964 else if(rel==relt::GE)
965 return relation(src2, relt::LE, src1, spec); // swapped
966
967 INVARIANT(
968 rel == relt::EQ || rel == relt::LT || rel == relt::LE,
969 "relation should be equality, less-than, or less-or-equal");
970
971 // special cases: -0 and 0 are equal
972 const exprt is_zero1 = is_zero(src1);
973 const exprt is_zero2 = is_zero(src2);
975
976 // NaN compares to nothing
977 exprt isnan1=isnan(src1, spec);
978 exprt isnan2=isnan(src2, spec);
979 const or_exprt nan(isnan1, isnan2);
980
981 if(rel==relt::LT || rel==relt::LE)
982 {
984
985 // signs different? trivial! Unless Zero.
986
988
989 // as long as the signs match: compare like unsigned numbers
990
991 // this works due to the BIAS
995 unsignedbv_typet(spec.width())),
996 ID_lt,
999 unsignedbv_typet(spec.width())));
1000
1001 // if both are negative (and not the same), need to turn around!
1004
1006
1007 if(rel==relt::LT)
1008 {
1010 // for the case of two negative numbers
1013 not_exprt(nan)}};
1014
1015 return std::move(and_bv);
1016 }
1017 else if(rel==relt::LE)
1018 {
1020
1021 return and_exprt(or_bv, not_exprt(nan));
1022 }
1023 else
1025 }
1026 else if(rel==relt::EQ)
1027 {
1029
1030 return and_exprt(
1032 not_exprt(nan));
1033 }
1034
1036 return false_exprt();
1037}
1038
1040 const exprt &src,
1041 const ieee_float_spect &spec)
1042{
1043 return and_exprt(
1044 exponent_all_ones(src, spec),
1045 fraction_all_zeros(src, spec));
1046}
1047
1049 const exprt &src,
1050 const ieee_float_spect &spec)
1051{
1052 return not_exprt(or_exprt(isinf(src, spec), isnan(src, spec)));
1053}
1054
1057 const exprt &src,
1058 const ieee_float_spect &spec)
1059{
1060 return extractbits_exprt(src, spec.f, unsignedbv_typet(spec.e));
1061}
1062
1065 const exprt &src,
1066 const ieee_float_spect &spec)
1067{
1068 return extractbits_exprt(src, 0, unsignedbv_typet(spec.f));
1069}
1070
1072 const exprt &src,
1073 const ieee_float_spect &spec)
1074{
1075 return and_exprt(exponent_all_ones(src, spec),
1076 not_exprt(fraction_all_zeros(src, spec)));
1077}
1078
1081 exprt &fraction,
1082 exprt &exponent)
1083{
1084 // n-log-n alignment shifter.
1085 // The worst-case shift is the number of fraction
1086 // bits minus one, in case the fraction is one exactly.
1087 std::size_t fraction_bits=to_unsignedbv_type(fraction.type()).get_width();
1088 std::size_t exponent_bits=to_signedbv_type(exponent.type()).get_width();
1090
1091 std::size_t depth = address_bits(fraction_bits - 1);
1092
1093 exponent = typecast_exprt(
1094 exponent, signedbv_typet(std::max(depth, exponent_bits + 1)));
1095
1096 exprt exponent_delta=from_integer(0, exponent.type());
1097
1098 for(int d=depth-1; d>=0; d--)
1099 {
1100 unsigned distance=(1<<d);
1101 INVARIANT(
1102 fraction_bits > distance,
1103 "distance must be within the range of fraction bits");
1104
1105 // check if first 'distance'-many bits are zeros
1106 const extractbits_exprt prefix(
1107 fraction, fraction_bits - distance, unsignedbv_typet(distance));
1108 const equal_exprt prefix_is_zero(prefix, from_integer(0, prefix.type()));
1109
1110 // If so, shift the zeros out left by 'distance'.
1111 // Otherwise, leave as is.
1112 const shl_exprt shifted(fraction, distance);
1113
1114 fraction=
1115 if_exprt(prefix_is_zero, shifted, fraction);
1116
1117 // add corresponding weight to exponent
1118 INVARIANT(
1119 d < (signed int)exponent_bits,
1120 "depth must be smaller than exponent bits");
1121
1125 }
1126
1127 exponent=minus_exprt(exponent, exponent_delta);
1128}
1129
1132 exprt &fraction,
1133 exprt &exponent,
1134 const ieee_float_spect &spec)
1135{
1136 mp_integer bias=spec.bias();
1137
1138 // Is the exponent strictly less than -bias+1, i.e., exponent<-bias+1?
1139 // This is transformed to distance=(-bias+1)-exponent
1140 // i.e., distance>0
1141 // Note that 1-bias is the exponent represented by 0...01,
1142 // i.e. the exponent of the smallest normal number and thus the 'base'
1143 // exponent for subnormal numbers.
1144
1145 std::size_t exponent_bits=to_signedbv_type(exponent.type()).get_width();
1146 PRECONDITION(exponent_bits >= spec.e);
1147
1148#if 1
1149 // Need to sign extend to avoid overflow. Note that this is a
1150 // relatively rare problem as the value needs to be close to the top
1151 // of the exponent range and then range must not have been
1152 // previously extended as add, multiply, etc. do. This is primarily
1153 // to handle casting down from larger ranges.
1154 exponent=typecast_exprt(exponent, signedbv_typet(exponent_bits+1));
1155#endif
1156
1157 const minus_exprt distance(
1158 from_integer(-bias + 1, exponent.type()), exponent);
1159
1160 // use sign bit
1161 const and_exprt denormal(
1162 not_exprt(sign_exprt(distance)),
1163 notequal_exprt(distance, from_integer(0, distance.type())));
1164
1165#if 1
1166 // Care must be taken to not loose information required for the
1167 // guard and sticky bits. +3 is for the hidden, guard and sticky bits.
1168 std::size_t fraction_bits=to_unsignedbv_type(fraction.type()).get_width();
1169
1170 if(fraction_bits < spec.f+3)
1171 {
1172 // Add zeros at the LSB end for the guard bit to shift into
1173 fraction=
1175 fraction, unsignedbv_typet(spec.f + 3 - fraction_bits).zero_expr(),
1176 unsignedbv_typet(spec.f+3));
1177 }
1178
1179 exprt denormalisedFraction = fraction;
1180
1183 sticky_right_shift(fraction, distance, sticky_bit);
1184
1188
1189 fraction=
1190 if_exprt(
1191 denormal,
1193 fraction);
1194
1195#else
1196 fraction=
1197 if_exprt(
1198 denormal,
1199 lshr_exprt(fraction, distance),
1200 fraction);
1201#endif
1202
1203 exponent=
1205 from_integer(-bias, exponent.type()),
1206 exponent);
1207}
1208
1210 const unbiased_floatt &src,
1211 const exprt &rm,
1212 const ieee_float_spect &spec) const
1213{
1214 // incoming: some fraction (with explicit 1),
1215 // some exponent without bias
1216 // outgoing: rounded, with right size, with hidden bit, bias
1217
1220
1221 {
1222 std::size_t exponent_bits = std::max(address_bits(spec.f), spec.e) + 1;
1223
1224 // before normalization, make sure exponent is large enough
1225 if(to_signedbv_type(aligned_exponent.type()).get_width()<exponent_bits)
1226 {
1227 // sign extend
1230 }
1231 }
1232
1233 // align it!
1236
1237 unbiased_floatt result;
1240 result.sign=src.sign;
1241 result.NaN=src.NaN;
1242 result.infinity=src.infinity;
1243
1244 rounding_mode_bitst rounding_mode_bits(rm);
1245 round_fraction(result, rounding_mode_bits, spec);
1246 round_exponent(result, rounding_mode_bits, spec);
1247
1248 return pack(bias(result, spec), spec);
1249}
1250
1253 const std::size_t dest_bits,
1254 const exprt sign,
1255 const exprt &fraction,
1256 const rounding_mode_bitst &rounding_mode_bits)
1257{
1258 std::size_t fraction_bits=
1259 to_unsignedbv_type(fraction.type()).get_width();
1260
1262
1263 // we have too many fraction bits
1265
1266 // more than two extra bits are superflus, and are
1267 // turned into a sticky bit
1268
1270
1271 if(extra_bits>=2)
1272 {
1273 // We keep most-significant bits, and thus the tail is made
1274 // of least-significant bits.
1275 const extractbits_exprt tail(
1276 fraction, 0, unsignedbv_typet(extra_bits - 2 + 1));
1277 sticky_bit=notequal_exprt(tail, from_integer(0, tail.type()));
1278 }
1279
1280 // the rounding bit is the last extra bit
1281 INVARIANT(
1282 extra_bits >= 1, "the extra bits contain at least the rounding bit");
1283 const extractbit_exprt rounding_bit(fraction, extra_bits - 1);
1284
1285 // we get one bit of the fraction for some rounding decisions
1287
1288 // round-to-nearest (ties to even)
1289 const and_exprt round_to_even(
1291
1292 // round up
1293 const and_exprt round_to_plus_inf(
1295
1296 // round down
1297 const and_exprt round_to_minus_inf(sign, or_exprt(rounding_bit, sticky_bit));
1298
1299 // round to zero
1300 false_exprt round_to_zero;
1301
1302 // round to away
1303 const auto round_to_away = or_exprt(rounding_bit, sticky_bit);
1304
1305 // now select appropriate one
1306 // clang-format off
1307 return if_exprt(rounding_mode_bits.round_to_even, round_to_even,
1308 if_exprt(rounding_mode_bits.round_to_plus_inf, round_to_plus_inf,
1309 if_exprt(rounding_mode_bits.round_to_minus_inf, round_to_minus_inf,
1310 if_exprt(rounding_mode_bits.round_to_zero, round_to_zero,
1311 if_exprt(rounding_mode_bits.round_to_away, round_to_away,
1312 false_exprt()))))); // otherwise zero
1313 // clang-format off
1314}
1315
1317 unbiased_floatt &result,
1318 const rounding_mode_bitst &rounding_mode_bits,
1319 const ieee_float_spect &spec)
1320{
1321 std::size_t fraction_size=spec.f+1;
1322 std::size_t result_fraction_size=
1323 to_unsignedbv_type(result.fraction.type()).get_width();
1324
1325 // do we need to enlarge the fraction?
1327 {
1328 // pad with zeros at bottom
1330
1332 result.fraction,
1333 unsignedbv_typet(padding).zero_expr(),
1335 }
1336 else if(result_fraction_size==fraction_size) // it stays
1337 {
1338 // do nothing
1339 }
1340 else // fraction gets smaller -- rounding
1341 {
1343 INVARIANT(
1344 extra_bits >= 1, "the extra bits include at least the rounding bit");
1345
1346 // this computes the rounding decision
1348 fraction_size, result.sign, result.fraction, rounding_mode_bits);
1349
1350 // chop off all the extra bits
1351 result.fraction = extractbits_exprt(
1353
1354#if 0
1355 // *** does not catch when the overflow goes subnormal -> normal ***
1356 // incrementing the fraction might result in an overflow
1357 result.fraction=
1358 bv_utils.zero_extension(result.fraction, result.fraction.size()+1);
1359
1360 result.fraction=bv_utils.incrementer(result.fraction, increment);
1361
1362 exprt overflow=result.fraction.back();
1363
1364 // In case of an overflow, the exponent has to be incremented.
1365 // "Post normalization" is then required.
1366 result.exponent=
1367 bv_utils.incrementer(result.exponent, overflow);
1368
1369 // post normalization of the fraction
1370 exprt integer_part1=result.fraction.back();
1371 exprt integer_part0=result.fraction[result.fraction.size()-2];
1373
1374 result.fraction.resize(result.fraction.size()-1);
1375 result.fraction.back()=new_integer_part;
1376
1377#else
1378 // When incrementing due to rounding there are two edge
1379 // cases we need to be aware of:
1380 // 1. If the number is normal, the increment can overflow.
1381 // In this case we need to increment the exponent and
1382 // set the MSB of the fraction to 1.
1383 // 2. If the number is the largest subnormal, the increment
1384 // can change the MSB making it normal. Thus the exponent
1385 // must be incremented but the fraction will be OK.
1387
1388 // increment if 'increment' is true
1389 result.fraction=
1390 plus_exprt(result.fraction,
1391 typecast_exprt(increment, result.fraction.type()));
1392
1393 // Normal overflow when old MSB == 1 and new MSB == 0
1396
1397 // Subnormal to normal transition when old MSB == 0 and new MSB == 1
1399
1400 // In case of an overflow or subnormal to normal conversion,
1401 // the exponent has to be incremented.
1402 result.exponent=
1403 plus_exprt(
1404 result.exponent,
1405 if_exprt(
1407 from_integer(1, result.exponent.type()),
1408 from_integer(0, result.exponent.type())));
1409
1410 // post normalization of the fraction
1411 // In the case of overflow, set the MSB to 1
1412 // The subnormal case will have (only) the MSB set to 1
1413 result.fraction=bitor_exprt(
1414 result.fraction,
1416 from_integer(1<<(fraction_size-1), result.fraction.type()),
1417 from_integer(0, result.fraction.type())));
1418#endif
1419 }
1420}
1421
1423 unbiased_floatt &result,
1424 const rounding_mode_bitst &rounding_mode_bits,
1425 const ieee_float_spect &spec)
1426{
1427 std::size_t result_exponent_size=
1428 to_signedbv_type(result.exponent.type()).get_width();
1429
1431
1432 // do we need to enlarge the exponent?
1433 if(result_exponent_size == spec.e) // it stays
1434 {
1435 // do nothing
1436 }
1437 else // exponent gets smaller -- chop off top bits
1438 {
1440 result.exponent =
1441 extractbits_exprt(result.exponent, 0, signedbv_typet(spec.e));
1442
1443 // max_exponent is the maximum representable
1444 // i.e. 1 higher than the maximum possible for a normal number
1445 exprt max_exponent=
1447 spec.max_exponent()-spec.bias(), old_exponent.type());
1448
1449 // the exponent is garbage if the fractional is zero
1450
1453 notequal_exprt(result.fraction, from_integer(0, result.fraction.type())));
1454
1455#if 1
1456 // Directed rounding modes round overflow to the maximum normal
1457 // depending on the particular mode and the sign
1459 rounding_mode_bits.round_to_even,
1460 or_exprt(
1461 and_exprt(rounding_mode_bits.round_to_plus_inf, not_exprt(result.sign)),
1462 and_exprt(rounding_mode_bits.round_to_minus_inf, result.sign)));
1463
1465
1468 spec.max_exponent()-(spec.bias() + 1), result.exponent.type());
1469
1470 result.exponent=
1472
1473 result.fraction=
1475 to_unsignedbv_type(result.fraction.type()).largest_expr(),
1476 result.fraction);
1477
1478 result.infinity=or_exprt(result.infinity,
1481#else
1483#endif
1484 }
1485}
1486
1489 const unbiased_floatt &src,
1490 const ieee_float_spect &spec)
1491{
1492 biased_floatt result;
1493
1494 result.sign=src.sign;
1495 result.NaN=src.NaN;
1496 result.infinity=src.infinity;
1497
1498 // we need to bias the new exponent
1499 result.exponent=add_bias(src.exponent, spec);
1500
1501 // strip off the hidden bit
1503 to_unsignedbv_type(src.fraction.type()).get_width() == spec.f + 1);
1504
1505 const extractbit_exprt hidden_bit(src.fraction, spec.f);
1507
1508 result.fraction =
1510
1511 // make exponent zero if its denormal
1512 // (includes zero)
1513 result.exponent=
1515 result.exponent);
1516
1517 return result;
1518}
1519
1521 const exprt &src,
1522 const ieee_float_spect &spec)
1523{
1524 typet t=unsignedbv_typet(spec.e);
1525 return plus_exprt(
1526 typecast_exprt(src, t),
1527 from_integer(spec.bias(), t));
1528}
1529
1531 const exprt &src,
1532 const ieee_float_spect &spec)
1533{
1534 typet t=signedbv_typet(spec.e);
1535 return minus_exprt(
1536 typecast_exprt(src, t),
1537 from_integer(spec.bias(), t));
1538}
1539
1541 const exprt &src,
1542 const ieee_float_spect &spec)
1543{
1544 unbiased_floatt result;
1545
1546 result.sign=sign_bit(src);
1547
1548 result.fraction=get_fraction(src, spec);
1549
1550 // add hidden bit
1551 exprt hidden_bit=isnormal(src, spec);
1552 result.fraction=
1554 unsignedbv_typet(spec.f+1));
1555
1556 result.exponent=get_exponent(src, spec);
1557
1558 // unbias the exponent
1560
1561 result.exponent=
1563 from_integer(-spec.bias()+1, signedbv_typet(spec.e)),
1564 sub_bias(result.exponent, spec));
1565
1566 result.infinity=isinf(src, spec);
1567 result.zero = is_zero(src);
1568 result.NaN=isnan(src, spec);
1569
1570 return result;
1571}
1572
1574 const biased_floatt &src,
1575 const ieee_float_spect &spec)
1576{
1577 PRECONDITION(to_unsignedbv_type(src.fraction.type()).get_width() == spec.f);
1578 PRECONDITION(to_unsignedbv_type(src.exponent.type()).get_width() == spec.e);
1579
1580 // do sign -- we make this 'false' for NaN
1581 const if_exprt sign_bit(src.NaN, false_exprt(), src.sign);
1582
1583 // the fraction is zero in case of infinity,
1584 // and one in case of NaN
1585 const if_exprt fraction(
1586 src.NaN,
1587 from_integer(1, src.fraction.type()),
1588 if_exprt(src.infinity, from_integer(0, src.fraction.type()), src.fraction));
1589
1590 const or_exprt infinity_or_NaN(src.NaN, src.infinity);
1591
1592 // do exponent
1593 const if_exprt exponent(
1595
1596 // stitch all three together
1597 return typecast_exprt(
1599 {std::move(sign_bit), std::move(exponent), std::move(fraction)},
1600 bv_typet(spec.f + spec.e + 1)),
1601 spec.to_type());
1602}
1603
1605 const exprt &op,
1606 const exprt &dist,
1607 exprt &sticky)
1608{
1609 std::size_t d=1, width=to_unsignedbv_type(op.type()).get_width();
1610 exprt result=op;
1612
1613 std::size_t dist_width=to_bitvector_type(dist.type()).get_width();
1614
1615 for(std::size_t stage=0; stage<dist_width; stage++)
1616 {
1617 const lshr_exprt tmp(result, d);
1618
1620
1621 if(d<=width)
1623 else
1624 lost_bits=result;
1625
1627
1628 sticky=
1629 or_exprt(
1630 and_exprt(
1631 dist_bit,
1633 sticky);
1634
1635 result=if_exprt(dist_bit, tmp, result);
1636
1637 d=d<<1;
1638 }
1639
1640 return result;
1641}
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:499
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:528
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:425
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:837
static exprt subtract_exponents(const unbiased_floatt &src1, const unbiased_floatt &src2)
Subtracts the exponents.
Definition float_bv.cpp:509
exprt div(const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:748
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:956
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:697
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:674
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