CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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_isnan)
136 {
137 const auto &op = to_unary_expr(expr).op();
138 return isnan(op, get_spec(op));
139 }
140 else if(expr.id()==ID_isfinite)
141 {
142 const auto &op = to_unary_expr(expr).op();
143 return isfinite(op, get_spec(op));
144 }
145 else if(expr.id()==ID_isinf)
146 {
147 const auto &op = to_unary_expr(expr).op();
148 return isinf(op, get_spec(op));
149 }
150 else if(expr.id()==ID_isnormal)
151 {
152 const auto &op = to_unary_expr(expr).op();
153 return isnormal(op, get_spec(op));
154 }
155 else if(expr.id()==ID_lt)
156 {
157 const auto &rel_expr = to_binary_relation_expr(expr);
158 return relation(
159 rel_expr.lhs(), relt::LT, rel_expr.rhs(), get_spec(rel_expr.lhs()));
160 }
161 else if(expr.id()==ID_gt)
162 {
163 const auto &rel_expr = to_binary_relation_expr(expr);
164 return relation(
165 rel_expr.lhs(), relt::GT, rel_expr.rhs(), get_spec(rel_expr.lhs()));
166 }
167 else if(expr.id()==ID_le)
168 {
169 const auto &rel_expr = to_binary_relation_expr(expr);
170 return relation(
171 rel_expr.lhs(), relt::LE, rel_expr.rhs(), get_spec(rel_expr.lhs()));
172 }
173 else if(expr.id()==ID_ge)
174 {
175 const auto &rel_expr = to_binary_relation_expr(expr);
176 return relation(
177 rel_expr.lhs(), relt::GE, rel_expr.rhs(), get_spec(rel_expr.lhs()));
178 }
179 else if(expr.id()==ID_sign)
180 return sign_bit(to_unary_expr(expr).op());
181
182 return nil_exprt();
183}
184
186{
187 const floatbv_typet &type=to_floatbv_type(expr.type());
188 return ieee_float_spect(type);
189}
190
192{
193 // we mask away the sign bit, which is the most significant bit
194 const mp_integer v = power(2, spec.width() - 1) - 1;
195
196 const constant_exprt mask(integer2bvrep(v, spec.width()), op.type());
197
198 return bitand_exprt(op, mask);
199}
200
202{
203 // we flip the sign bit with an xor
204 const mp_integer v = power(2, spec.width() - 1);
205
206 constant_exprt mask(integer2bvrep(v, spec.width()), op.type());
207
208 return bitxor_exprt(op, mask);
209}
210
212 const exprt &src0,
213 const exprt &src1,
214 const ieee_float_spect &spec)
215{
216 // special cases: -0 and 0 are equal
217 const exprt is_zero0 = is_zero(src0);
218 const exprt is_zero1 = is_zero(src1);
220
221 // NaN compares to nothing
222 exprt isnan0=isnan(src0, spec);
223 exprt isnan1=isnan(src1, spec);
224 const or_exprt nan(isnan0, isnan1);
225
227
228 return and_exprt(
230 not_exprt(nan));
231}
232
234{
235 // we mask away the sign bit, which is the most significant bit
236 const floatbv_typet &type=to_floatbv_type(src.type());
237 std::size_t width=type.get_width();
238
239 const mp_integer v = power(2, width - 1) - 1;
240
241 constant_exprt mask(integer2bvrep(v, width), src.type());
242
243 ieee_float_valuet z(type);
244 z.make_zero();
245
246 return equal_exprt(bitand_exprt(src, mask), z.to_expr());
247}
248
250 const exprt &src,
251 const ieee_float_spect &spec)
252{
253 exprt exponent=get_exponent(src, spec);
254 exprt all_ones=to_unsignedbv_type(exponent.type()).largest_expr();
255 return equal_exprt(exponent, all_ones);
256}
257
259 const exprt &src,
260 const ieee_float_spect &spec)
261{
262 exprt exponent=get_exponent(src, spec);
263 exprt all_zeros=to_unsignedbv_type(exponent.type()).zero_expr();
264 return equal_exprt(exponent, all_zeros);
265}
266
268 const exprt &src,
269 const ieee_float_spect &spec)
270{
271 // does not include hidden bit
272 exprt fraction=get_fraction(src, spec);
273 exprt all_zeros=to_unsignedbv_type(fraction.type()).zero_expr();
274 return equal_exprt(fraction, all_zeros);
275}
276
294
296{
298 std::size_t width=bv_type.get_width();
299 return extractbit_exprt(op, width-1);
300}
301
303 const exprt &src,
304 const exprt &rm,
305 const ieee_float_spect &spec) const
306{
307 std::size_t src_width=to_signedbv_type(src.type()).get_width();
308
309 unbiased_floatt result;
310
311 // we need to adjust for negative integers
312 result.sign=sign_bit(src);
313
314 result.fraction=
316
317 // build an exponent (unbiased) -- this is signed!
318 result.exponent=
320 src_width-1,
322
323 return rounder(result, rm, spec);
324}
325
327 const exprt &src,
328 const exprt &rm,
329 const ieee_float_spect &spec) const
330{
331 unbiased_floatt result;
332
333 result.fraction=src;
334
335 std::size_t src_width=to_unsignedbv_type(src.type()).get_width();
336
337 // build an exponent (unbiased) -- this is signed!
338 result.exponent=
340 src_width-1,
342
343 result.sign=false_exprt();
344
345 return rounder(result, rm, spec);
346}
347
349 const exprt &src,
350 std::size_t dest_width,
351 const exprt &rm,
352 const ieee_float_spect &spec)
353{
354 return to_integer(src, dest_width, true, rm, spec);
355}
356
358 const exprt &src,
359 std::size_t dest_width,
360 const exprt &rm,
361 const ieee_float_spect &spec)
362{
363 return to_integer(src, dest_width, false, rm, spec);
364}
365
367 const exprt &src,
368 std::size_t dest_width,
369 bool is_signed,
370 const exprt &rm,
371 const ieee_float_spect &spec)
372{
373 const unbiased_floatt unpacked=unpack(src, spec);
374
375 rounding_mode_bitst rounding_mode_bits(rm);
376
377 // Right now hard-wired to round-to-zero, which is
378 // the usual case in ANSI-C.
379
380 // if the exponent is positive, shift right
381 exprt offset=from_integer(spec.f, signedbv_typet(spec.e));
382 const minus_exprt distance(offset, unpacked.exponent);
383 const lshr_exprt shift_result(unpacked.fraction, distance);
384
385 // if the exponent is negative, we have zero anyways
386 exprt result=shift_result;
387 const sign_exprt exponent_sign(unpacked.exponent);
388
389 result=
390 if_exprt(exponent_sign, from_integer(0, result.type()), result);
391
392 // chop out the right number of bits from the result
393 typet result_type=
395 static_cast<typet>(unsignedbv_typet(dest_width));
396
397 result=typecast_exprt(result, result_type);
398
399 // if signed, apply sign.
400 if(is_signed)
401 {
402 result=if_exprt(
403 unpacked.sign, unary_minus_exprt(result), result);
404 }
405 else
406 {
407 // It's unclear what the behaviour for negative floats
408 // to integer shall be.
409 }
410
411 return result;
412}
413
415 const exprt &src,
416 const exprt &rm,
418 const ieee_float_spect &dest_spec) const
419{
420 // Catch the special case in which we extend,
421 // e.g. single to double.
422 // In this case, rounding can be avoided,
423 // but a denormal number may be come normal.
424 // Be careful to exclude the difficult case
425 // when denormalised numbers in the old format
426 // can be converted to denormalised numbers in the
427 // new format. Note that this is rare and will only
428 // happen with very non-standard formats.
429
430 int sourceSmallestNormalExponent = -((1 << (src_spec.e - 1)) - 1);
433
434 // Using the fact that f doesn't include the hidden bit
435
436 int destSmallestNormalExponent = -((1 << (dest_spec.e - 1)) - 1);
437
438 if(dest_spec.e>=src_spec.e &&
439 dest_spec.f>=src_spec.f &&
441 {
443 unbiased_floatt result;
444
445 // the fraction gets zero-padded
446 std::size_t padding=dest_spec.f-src_spec.f;
447 result.fraction=
449 unpacked_src.fraction,
452
453 // the exponent gets sign-extended
454 INVARIANT(
455 unpacked_src.exponent.type().id() == ID_signedbv,
456 "the exponent needs to have a signed type");
457 result.exponent=
459
460 // if the number was denormal and is normal in the new format,
461 // normalise it!
462 if(dest_spec.e > src_spec.e)
463 {
464 normalization_shift(result.fraction, result.exponent);
465 // normalization_shift unconditionally extends the exponent size to avoid
466 // arithmetic overflow, but this cannot have happened here as the exponent
467 // had already been extended to dest_spec's size
468 result.exponent =
470 }
471
472 // the flags get copied
473 result.sign=unpacked_src.sign;
474 result.NaN=unpacked_src.NaN;
475 result.infinity=unpacked_src.infinity;
476
477 // no rounding needed!
478 return pack(bias(result, dest_spec), dest_spec);
479 }
480 else
481 {
482 // we actually need to round
483 unbiased_floatt result=unpack(src, src_spec);
484 return rounder(result, rm, dest_spec);
485 }
486}
487
489 const exprt &src,
490 const ieee_float_spect &spec)
491{
492 return and_exprt(
493 not_exprt(exponent_all_zeros(src, spec)),
494 not_exprt(exponent_all_ones(src, spec)));
495}
496
499 const unbiased_floatt &src1,
500 const unbiased_floatt &src2)
501{
502 // extend both by one bit
503 std::size_t old_width1=to_signedbv_type(src1.exponent.type()).get_width();
504 std::size_t old_width2=to_signedbv_type(src2.exponent.type()).get_width();
506
508 src1.exponent, signedbv_typet(old_width1 + 1));
509
511 src2.exponent, signedbv_typet(old_width2 + 1));
512
513 // compute shift distance (here is the subtraction)
515}
516
518 bool subtract,
519 const exprt &op0,
520 const exprt &op1,
521 const exprt &rm,
522 const ieee_float_spect &spec) const
523{
526
527 // subtract?
528 if(subtract)
529 unpacked2.sign=not_exprt(unpacked2.sign);
530
531 // figure out which operand has the bigger exponent
534
536 if_exprt(src2_bigger, unpacked2.exponent, unpacked1.exponent);
537
538 // swap fractions as needed
539 const exprt new_fraction1=
540 if_exprt(src2_bigger, unpacked2.fraction, unpacked1.fraction);
541
542 const exprt new_fraction2=
543 if_exprt(src2_bigger, unpacked1.fraction, unpacked2.fraction);
544
545 // compute distance
546 const exprt distance=
548
549 // limit the distance: shifting more than f+3 bits is unnecessary
550 const exprt limited_dist=limit_distance(distance, spec.f+3);
551
552 // pad fractions with 3 zeros from below
554 // add 4 to spec.f because unpacked new_fraction has the hidden bit
559
560 // shift new_fraction2
565
566 // sticky bit: 'or' of the bits lost by the right-shift
570 from_integer(0, unsignedbv_typet(spec.f + 3)),
572 fraction2_shifted.type()));
573
574 // need to have two extra fraction bits for addition and rounding
575 const exprt fraction1_ext=
577 const exprt fraction2_ext=
579
580 unbiased_floatt result;
581
582 // now add/sub them
584
585 result.fraction=
589
590 // sign of result
591 std::size_t width=to_bitvector_type(result.fraction.type()).get_width();
593 typecast_exprt(result.fraction, signedbv_typet(width)));
594 result.fraction=
597 unsignedbv_typet(width));
598
600
601 // adjust the exponent for the fact that we added two bits to the fraction
602 result.exponent=
604 from_integer(2, signedbv_typet(spec.e+1)));
605
606 // NaN?
607 result.NaN=or_exprt(
608 and_exprt(and_exprt(unpacked1.infinity, unpacked2.infinity),
610 or_exprt(unpacked1.NaN, unpacked2.NaN));
611
612 // infinity?
613 result.infinity=and_exprt(
614 not_exprt(result.NaN),
615 or_exprt(unpacked1.infinity, unpacked2.infinity));
616
617 // zero?
618 // Note that:
619 // 1. The zero flag isn't used apart from in divide and
620 // is only set on unpack
621 // 2. Subnormals mean that addition or subtraction can't round to 0,
622 // thus we can perform this test now
623 // 3. The rules for sign are different for zero
624 result.zero=
625 and_exprt(
626 not_exprt(or_exprt(result.infinity, result.NaN)),
628 result.fraction,
629 from_integer(0, result.fraction.type())));
630
631 // sign
634
636 unpacked1.infinity, unpacked1.sign, unpacked2.sign);
637
638 #if 1
639 rounding_mode_bitst rounding_mode_bits(rm);
640
641 const if_exprt zero_sign(
642 rounding_mode_bits.round_to_minus_inf,
643 or_exprt(unpacked1.sign, unpacked2.sign),
644 and_exprt(unpacked1.sign, unpacked2.sign));
645
646 result.sign=if_exprt(
647 result.infinity,
649 if_exprt(result.zero,
650 zero_sign,
651 add_sub_sign));
652 #else
653 result.sign=if_exprt(
654 result.infinity,
657 #endif
658
659 return rounder(result, rm, spec);
660}
661
664 const exprt &dist,
666{
667 std::size_t nb_bits = address_bits(limit);
668 std::size_t dist_width=to_unsignedbv_type(dist.type()).get_width();
669
671 return dist;
672
677
679
680 return if_exprt(
683 unsignedbv_typet(nb_bits).largest_expr());
684}
685
687 const exprt &src1,
688 const exprt &src2,
689 const exprt &rm,
690 const ieee_float_spect &spec) const
691{
692 // unpack
695
696 // zero-extend the fractions (unpacked fraction has the hidden bit)
698 const exprt fraction1 =
700 const exprt fraction2 =
702
703 // multiply the fractions
704 unbiased_floatt result;
706
707 // extend exponents to account for overflow
708 // add two bits, as we do extra arithmetic on it later
712
714
715 // Adjust exponent; we are thowing in an extra fraction bit,
716 // it has been extended above.
717 result.exponent=
719
720 // new sign
721 result.sign=notequal_exprt(unpacked1.sign, unpacked2.sign);
722
723 // infinity?
724 result.infinity=or_exprt(unpacked1.infinity, unpacked2.infinity);
725
726 // NaN?
727 result.NaN = disjunction(
728 {isnan(src1, spec),
729 isnan(src2, spec),
730 // infinity * 0 is NaN!
731 and_exprt(unpacked1.zero, unpacked2.infinity),
732 and_exprt(unpacked2.zero, unpacked1.infinity)});
733
734 return rounder(result, rm, spec);
735}
736
738 const exprt &src1,
739 const exprt &src2,
740 const exprt &rm,
741 const ieee_float_spect &spec) const
742{
743 // unpack
746
747 std::size_t fraction_width=
748 to_unsignedbv_type(unpacked1.fraction.type()).get_width();
749 std::size_t div_width=fraction_width*2+1;
750
751 // pad fraction1 with zeros
753 unpacked1.fraction,
754 from_integer(0, unsignedbv_typet(div_width - fraction_width)),
756
757 // zero-extend fraction2 to match fraction1
758 const zero_extend_exprt fraction2{unpacked2.fraction, fraction1.type()};
759
760 // divide fractions
761 unbiased_floatt result;
762 exprt rem;
763
764 // the below should be merged somehow
767
768 // is there a remainder?
769 const notequal_exprt have_remainder(rem, from_integer(0, rem.type()));
770
771 // we throw this into the result, as least-significant bit,
772 // to get the right rounding decision
773 result.fraction=
776
777 // We will subtract the exponents;
778 // to account for overflow, we add a bit.
780 unpacked1.exponent, signedbv_typet(spec.e + 1));
782 unpacked2.exponent, signedbv_typet(spec.e + 1));
783
784 // subtract exponents
786
787 // adjust, as we have thown in extra fraction bits
788 result.exponent=plus_exprt(
790 from_integer(spec.f, added_exponent.type()));
791
792 // new sign
793 result.sign=notequal_exprt(unpacked1.sign, unpacked2.sign);
794
795 // Infinity? This happens when
796 // 1) dividing a non-nan/non-zero by zero, or
797 // 2) first operand is inf and second is non-nan and non-zero
798 // In particular, inf/0=inf.
799 result.infinity=
800 or_exprt(
803 unpacked2.zero)),
804 and_exprt(unpacked1.infinity,
806 not_exprt(unpacked2.zero))));
807
808 // NaN?
809 result.NaN=or_exprt(unpacked1.NaN,
812 and_exprt(unpacked1.infinity, unpacked2.infinity))));
813
814 // Division by infinity produces zero, unless we have NaN
815 const and_exprt force_zero(not_exprt(unpacked1.NaN), unpacked2.infinity);
816
817 result.fraction=
818 if_exprt(
820 from_integer(0, result.fraction.type()),
821 result.fraction);
822
823 return rounder(result, rm, spec);
824}
825
827 const exprt &src1,
828 relt rel,
829 const exprt &src2,
830 const ieee_float_spect &spec)
831{
832 if(rel==relt::GT)
833 return relation(src2, relt::LT, src1, spec); // swapped
834 else if(rel==relt::GE)
835 return relation(src2, relt::LE, src1, spec); // swapped
836
837 INVARIANT(
838 rel == relt::EQ || rel == relt::LT || rel == relt::LE,
839 "relation should be equality, less-than, or less-or-equal");
840
841 // special cases: -0 and 0 are equal
842 const exprt is_zero1 = is_zero(src1);
843 const exprt is_zero2 = is_zero(src2);
845
846 // NaN compares to nothing
847 exprt isnan1=isnan(src1, spec);
848 exprt isnan2=isnan(src2, spec);
849 const or_exprt nan(isnan1, isnan2);
850
851 if(rel==relt::LT || rel==relt::LE)
852 {
854
855 // signs different? trivial! Unless Zero.
856
858
859 // as long as the signs match: compare like unsigned numbers
860
861 // this works due to the BIAS
865 unsignedbv_typet(spec.width())),
866 ID_lt,
869 unsignedbv_typet(spec.width())));
870
871 // if both are negative (and not the same), need to turn around!
874
876
877 if(rel==relt::LT)
878 {
880 // for the case of two negative numbers
883 not_exprt(nan)}};
884
885 return std::move(and_bv);
886 }
887 else if(rel==relt::LE)
888 {
890
891 return and_exprt(or_bv, not_exprt(nan));
892 }
893 else
895 }
896 else if(rel==relt::EQ)
897 {
899
900 return and_exprt(
902 not_exprt(nan));
903 }
904
906 return false_exprt();
907}
908
910 const exprt &src,
911 const ieee_float_spect &spec)
912{
913 return and_exprt(
914 exponent_all_ones(src, spec),
915 fraction_all_zeros(src, spec));
916}
917
919 const exprt &src,
920 const ieee_float_spect &spec)
921{
922 return not_exprt(or_exprt(isinf(src, spec), isnan(src, spec)));
923}
924
927 const exprt &src,
928 const ieee_float_spect &spec)
929{
930 return extractbits_exprt(src, spec.f, unsignedbv_typet(spec.e));
931}
932
935 const exprt &src,
936 const ieee_float_spect &spec)
937{
938 return extractbits_exprt(src, 0, unsignedbv_typet(spec.f));
939}
940
942 const exprt &src,
943 const ieee_float_spect &spec)
944{
945 return and_exprt(exponent_all_ones(src, spec),
946 not_exprt(fraction_all_zeros(src, spec)));
947}
948
951 exprt &fraction,
952 exprt &exponent)
953{
954 // n-log-n alignment shifter.
955 // The worst-case shift is the number of fraction
956 // bits minus one, in case the fraction is one exactly.
957 std::size_t fraction_bits=to_unsignedbv_type(fraction.type()).get_width();
958 std::size_t exponent_bits=to_signedbv_type(exponent.type()).get_width();
960
961 std::size_t depth = address_bits(fraction_bits - 1);
962
963 exponent = typecast_exprt(
964 exponent, signedbv_typet(std::max(depth, exponent_bits + 1)));
965
966 exprt exponent_delta=from_integer(0, exponent.type());
967
968 for(int d=depth-1; d>=0; d--)
969 {
970 unsigned distance=(1<<d);
971 INVARIANT(
972 fraction_bits > distance,
973 "distance must be within the range of fraction bits");
974
975 // check if first 'distance'-many bits are zeros
976 const extractbits_exprt prefix(
977 fraction, fraction_bits - distance, unsignedbv_typet(distance));
978 const equal_exprt prefix_is_zero(prefix, from_integer(0, prefix.type()));
979
980 // If so, shift the zeros out left by 'distance'.
981 // Otherwise, leave as is.
982 const shl_exprt shifted(fraction, distance);
983
984 fraction=
985 if_exprt(prefix_is_zero, shifted, fraction);
986
987 // add corresponding weight to exponent
988 INVARIANT(
989 d < (signed int)exponent_bits,
990 "depth must be smaller than exponent bits");
991
995 }
996
997 exponent=minus_exprt(exponent, exponent_delta);
998}
999
1002 exprt &fraction,
1003 exprt &exponent,
1004 const ieee_float_spect &spec)
1005{
1006 mp_integer bias=spec.bias();
1007
1008 // Is the exponent strictly less than -bias+1, i.e., exponent<-bias+1?
1009 // This is transformed to distance=(-bias+1)-exponent
1010 // i.e., distance>0
1011 // Note that 1-bias is the exponent represented by 0...01,
1012 // i.e. the exponent of the smallest normal number and thus the 'base'
1013 // exponent for subnormal numbers.
1014
1015 std::size_t exponent_bits=to_signedbv_type(exponent.type()).get_width();
1016 PRECONDITION(exponent_bits >= spec.e);
1017
1018#if 1
1019 // Need to sign extend to avoid overflow. Note that this is a
1020 // relatively rare problem as the value needs to be close to the top
1021 // of the exponent range and then range must not have been
1022 // previously extended as add, multiply, etc. do. This is primarily
1023 // to handle casting down from larger ranges.
1024 exponent=typecast_exprt(exponent, signedbv_typet(exponent_bits+1));
1025#endif
1026
1027 const minus_exprt distance(
1028 from_integer(-bias + 1, exponent.type()), exponent);
1029
1030 // use sign bit
1031 const and_exprt denormal(
1032 not_exprt(sign_exprt(distance)),
1033 notequal_exprt(distance, from_integer(0, distance.type())));
1034
1035#if 1
1036 // Care must be taken to not loose information required for the
1037 // guard and sticky bits. +3 is for the hidden, guard and sticky bits.
1038 std::size_t fraction_bits=to_unsignedbv_type(fraction.type()).get_width();
1039
1040 if(fraction_bits < spec.f+3)
1041 {
1042 // Add zeros at the LSB end for the guard bit to shift into
1043 fraction=
1045 fraction, unsignedbv_typet(spec.f + 3 - fraction_bits).zero_expr(),
1046 unsignedbv_typet(spec.f+3));
1047 }
1048
1049 exprt denormalisedFraction = fraction;
1050
1053 sticky_right_shift(fraction, distance, sticky_bit);
1054
1058
1059 fraction=
1060 if_exprt(
1061 denormal,
1063 fraction);
1064
1065#else
1066 fraction=
1067 if_exprt(
1068 denormal,
1069 lshr_exprt(fraction, distance),
1070 fraction);
1071#endif
1072
1073 exponent=
1075 from_integer(-bias, exponent.type()),
1076 exponent);
1077}
1078
1080 const unbiased_floatt &src,
1081 const exprt &rm,
1082 const ieee_float_spect &spec) const
1083{
1084 // incoming: some fraction (with explicit 1),
1085 // some exponent without bias
1086 // outgoing: rounded, with right size, with hidden bit, bias
1087
1090
1091 {
1092 std::size_t exponent_bits = std::max(address_bits(spec.f), spec.e) + 1;
1093
1094 // before normalization, make sure exponent is large enough
1095 if(to_signedbv_type(aligned_exponent.type()).get_width()<exponent_bits)
1096 {
1097 // sign extend
1100 }
1101 }
1102
1103 // align it!
1106
1107 unbiased_floatt result;
1110 result.sign=src.sign;
1111 result.NaN=src.NaN;
1112 result.infinity=src.infinity;
1113
1114 rounding_mode_bitst rounding_mode_bits(rm);
1115 round_fraction(result, rounding_mode_bits, spec);
1116 round_exponent(result, rounding_mode_bits, spec);
1117
1118 return pack(bias(result, spec), spec);
1119}
1120
1123 const std::size_t dest_bits,
1124 const exprt sign,
1125 const exprt &fraction,
1126 const rounding_mode_bitst &rounding_mode_bits)
1127{
1128 std::size_t fraction_bits=
1129 to_unsignedbv_type(fraction.type()).get_width();
1130
1132
1133 // we have too many fraction bits
1135
1136 // more than two extra bits are superflus, and are
1137 // turned into a sticky bit
1138
1140
1141 if(extra_bits>=2)
1142 {
1143 // We keep most-significant bits, and thus the tail is made
1144 // of least-significant bits.
1145 const extractbits_exprt tail(
1146 fraction, 0, unsignedbv_typet(extra_bits - 2 + 1));
1147 sticky_bit=notequal_exprt(tail, from_integer(0, tail.type()));
1148 }
1149
1150 // the rounding bit is the last extra bit
1151 INVARIANT(
1152 extra_bits >= 1, "the extra bits contain at least the rounding bit");
1153 const extractbit_exprt rounding_bit(fraction, extra_bits - 1);
1154
1155 // we get one bit of the fraction for some rounding decisions
1157
1158 // round-to-nearest (ties to even)
1159 const and_exprt round_to_even(
1161
1162 // round up
1163 const and_exprt round_to_plus_inf(
1165
1166 // round down
1167 const and_exprt round_to_minus_inf(sign, or_exprt(rounding_bit, sticky_bit));
1168
1169 // round to zero
1170 false_exprt round_to_zero;
1171
1172 // round to away
1173 const auto round_to_away = or_exprt(rounding_bit, sticky_bit);
1174
1175 // now select appropriate one
1176 // clang-format off
1177 return if_exprt(rounding_mode_bits.round_to_even, round_to_even,
1178 if_exprt(rounding_mode_bits.round_to_plus_inf, round_to_plus_inf,
1179 if_exprt(rounding_mode_bits.round_to_minus_inf, round_to_minus_inf,
1180 if_exprt(rounding_mode_bits.round_to_zero, round_to_zero,
1181 if_exprt(rounding_mode_bits.round_to_away, round_to_away,
1182 false_exprt()))))); // otherwise zero
1183 // clang-format off
1184}
1185
1187 unbiased_floatt &result,
1188 const rounding_mode_bitst &rounding_mode_bits,
1189 const ieee_float_spect &spec)
1190{
1191 std::size_t fraction_size=spec.f+1;
1192 std::size_t result_fraction_size=
1193 to_unsignedbv_type(result.fraction.type()).get_width();
1194
1195 // do we need to enlarge the fraction?
1197 {
1198 // pad with zeros at bottom
1200
1202 result.fraction,
1203 unsignedbv_typet(padding).zero_expr(),
1205 }
1206 else if(result_fraction_size==fraction_size) // it stays
1207 {
1208 // do nothing
1209 }
1210 else // fraction gets smaller -- rounding
1211 {
1213 INVARIANT(
1214 extra_bits >= 1, "the extra bits include at least the rounding bit");
1215
1216 // this computes the rounding decision
1218 fraction_size, result.sign, result.fraction, rounding_mode_bits);
1219
1220 // chop off all the extra bits
1221 result.fraction = extractbits_exprt(
1223
1224#if 0
1225 // *** does not catch when the overflow goes subnormal -> normal ***
1226 // incrementing the fraction might result in an overflow
1227 result.fraction=
1228 bv_utils.zero_extension(result.fraction, result.fraction.size()+1);
1229
1230 result.fraction=bv_utils.incrementer(result.fraction, increment);
1231
1232 exprt overflow=result.fraction.back();
1233
1234 // In case of an overflow, the exponent has to be incremented.
1235 // "Post normalization" is then required.
1236 result.exponent=
1237 bv_utils.incrementer(result.exponent, overflow);
1238
1239 // post normalization of the fraction
1240 exprt integer_part1=result.fraction.back();
1241 exprt integer_part0=result.fraction[result.fraction.size()-2];
1243
1244 result.fraction.resize(result.fraction.size()-1);
1245 result.fraction.back()=new_integer_part;
1246
1247#else
1248 // When incrementing due to rounding there are two edge
1249 // cases we need to be aware of:
1250 // 1. If the number is normal, the increment can overflow.
1251 // In this case we need to increment the exponent and
1252 // set the MSB of the fraction to 1.
1253 // 2. If the number is the largest subnormal, the increment
1254 // can change the MSB making it normal. Thus the exponent
1255 // must be incremented but the fraction will be OK.
1257
1258 // increment if 'increment' is true
1259 result.fraction=
1260 plus_exprt(result.fraction,
1261 typecast_exprt(increment, result.fraction.type()));
1262
1263 // Normal overflow when old MSB == 1 and new MSB == 0
1266
1267 // Subnormal to normal transition when old MSB == 0 and new MSB == 1
1269
1270 // In case of an overflow or subnormal to normal conversion,
1271 // the exponent has to be incremented.
1272 result.exponent=
1273 plus_exprt(
1274 result.exponent,
1275 if_exprt(
1277 from_integer(1, result.exponent.type()),
1278 from_integer(0, result.exponent.type())));
1279
1280 // post normalization of the fraction
1281 // In the case of overflow, set the MSB to 1
1282 // The subnormal case will have (only) the MSB set to 1
1283 result.fraction=bitor_exprt(
1284 result.fraction,
1286 from_integer(1<<(fraction_size-1), result.fraction.type()),
1287 from_integer(0, result.fraction.type())));
1288#endif
1289 }
1290}
1291
1293 unbiased_floatt &result,
1294 const rounding_mode_bitst &rounding_mode_bits,
1295 const ieee_float_spect &spec)
1296{
1297 std::size_t result_exponent_size=
1298 to_signedbv_type(result.exponent.type()).get_width();
1299
1301
1302 // do we need to enlarge the exponent?
1303 if(result_exponent_size == spec.e) // it stays
1304 {
1305 // do nothing
1306 }
1307 else // exponent gets smaller -- chop off top bits
1308 {
1310 result.exponent =
1311 extractbits_exprt(result.exponent, 0, signedbv_typet(spec.e));
1312
1313 // max_exponent is the maximum representable
1314 // i.e. 1 higher than the maximum possible for a normal number
1315 exprt max_exponent=
1317 spec.max_exponent()-spec.bias(), old_exponent.type());
1318
1319 // the exponent is garbage if the fractional is zero
1320
1323 notequal_exprt(result.fraction, from_integer(0, result.fraction.type())));
1324
1325#if 1
1326 // Directed rounding modes round overflow to the maximum normal
1327 // depending on the particular mode and the sign
1329 rounding_mode_bits.round_to_even,
1330 or_exprt(
1331 and_exprt(rounding_mode_bits.round_to_plus_inf, not_exprt(result.sign)),
1332 and_exprt(rounding_mode_bits.round_to_minus_inf, result.sign)));
1333
1335
1338 spec.max_exponent()-(spec.bias() + 1), result.exponent.type());
1339
1340 result.exponent=
1342
1343 result.fraction=
1345 to_unsignedbv_type(result.fraction.type()).largest_expr(),
1346 result.fraction);
1347
1348 result.infinity=or_exprt(result.infinity,
1351#else
1353#endif
1354 }
1355}
1356
1359 const unbiased_floatt &src,
1360 const ieee_float_spect &spec)
1361{
1362 biased_floatt result;
1363
1364 result.sign=src.sign;
1365 result.NaN=src.NaN;
1366 result.infinity=src.infinity;
1367
1368 // we need to bias the new exponent
1369 result.exponent=add_bias(src.exponent, spec);
1370
1371 // strip off the hidden bit
1373 to_unsignedbv_type(src.fraction.type()).get_width() == spec.f + 1);
1374
1375 const extractbit_exprt hidden_bit(src.fraction, spec.f);
1377
1378 result.fraction =
1380
1381 // make exponent zero if its denormal
1382 // (includes zero)
1383 result.exponent=
1385 result.exponent);
1386
1387 return result;
1388}
1389
1391 const exprt &src,
1392 const ieee_float_spect &spec)
1393{
1394 typet t=unsignedbv_typet(spec.e);
1395 return plus_exprt(
1396 typecast_exprt(src, t),
1397 from_integer(spec.bias(), t));
1398}
1399
1401 const exprt &src,
1402 const ieee_float_spect &spec)
1403{
1404 typet t=signedbv_typet(spec.e);
1405 return minus_exprt(
1406 typecast_exprt(src, t),
1407 from_integer(spec.bias(), t));
1408}
1409
1411 const exprt &src,
1412 const ieee_float_spect &spec)
1413{
1414 unbiased_floatt result;
1415
1416 result.sign=sign_bit(src);
1417
1418 result.fraction=get_fraction(src, spec);
1419
1420 // add hidden bit
1421 exprt hidden_bit=isnormal(src, spec);
1422 result.fraction=
1424 unsignedbv_typet(spec.f+1));
1425
1426 result.exponent=get_exponent(src, spec);
1427
1428 // unbias the exponent
1430
1431 result.exponent=
1433 from_integer(-spec.bias()+1, signedbv_typet(spec.e)),
1434 sub_bias(result.exponent, spec));
1435
1436 result.infinity=isinf(src, spec);
1437 result.zero = is_zero(src);
1438 result.NaN=isnan(src, spec);
1439
1440 return result;
1441}
1442
1444 const biased_floatt &src,
1445 const ieee_float_spect &spec)
1446{
1447 PRECONDITION(to_unsignedbv_type(src.fraction.type()).get_width() == spec.f);
1448 PRECONDITION(to_unsignedbv_type(src.exponent.type()).get_width() == spec.e);
1449
1450 // do sign -- we make this 'false' for NaN
1451 const if_exprt sign_bit(src.NaN, false_exprt(), src.sign);
1452
1453 // the fraction is zero in case of infinity,
1454 // and one in case of NaN
1455 const if_exprt fraction(
1456 src.NaN,
1457 from_integer(1, src.fraction.type()),
1458 if_exprt(src.infinity, from_integer(0, src.fraction.type()), src.fraction));
1459
1460 const or_exprt infinity_or_NaN(src.NaN, src.infinity);
1461
1462 // do exponent
1463 const if_exprt exponent(
1465
1466 // stitch all three together
1467 return typecast_exprt(
1469 {std::move(sign_bit), std::move(exponent), std::move(fraction)},
1470 bv_typet(spec.f + spec.e + 1)),
1471 spec.to_type());
1472}
1473
1475 const exprt &op,
1476 const exprt &dist,
1477 exprt &sticky)
1478{
1479 std::size_t d=1, width=to_unsignedbv_type(op.type()).get_width();
1480 exprt result=op;
1482
1483 std::size_t dist_width=to_bitvector_type(dist.type()).get_width();
1484
1485 for(std::size_t stage=0; stage<dist_width; stage++)
1486 {
1487 const lshr_exprt tmp(result, d);
1488
1490
1491 if(d<=width)
1493 else
1494 lost_bits=result;
1495
1497
1498 sticky=
1499 or_exprt(
1500 and_exprt(
1501 dist_bit,
1503 sticky);
1504
1505 result=if_exprt(dist_bit, tmp, result);
1506
1507 d=d<<1;
1508 }
1509
1510 return result;
1511}
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:442
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Boolean AND.
Definition std_expr.h:2125
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition std_expr.h:762
Bit-wise AND.
Bit-wise OR.
Base class of fixed-width bit-vector types.
Definition std_types.h:909
std::size_t get_width() const
Definition std_types.h:925
Bit-wise XOR.
Fixed-width bit-vector without numerical interpretation.
Concatenation of bit-vector operands.
A constant literal expression.
Definition std_expr.h:3117
Division.
Definition std_expr.h:1157
Equality.
Definition std_expr.h:1366
Base class for all expressions.
Definition expr.h:56
bool is_boolean() const
Return whether the expression represents a Boolean.
Definition expr.h:224
typet & type()
Return the type of the expression.
Definition expr.h:84
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:3199
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
Definition float_bv.cpp:950
static exprt get_fraction(const exprt &, const ieee_float_spect &)
Gets the fraction without hidden bit in a floating-point bit-vector src.
Definition float_bv.cpp:934
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:249
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:366
exprt from_unsigned_integer(const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:326
static exprt isfinite(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:918
static exprt isnormal(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:488
exprt from_signed_integer(const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:302
exprt add_sub(bool subtract, const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:517
static exprt is_zero(const exprt &)
Definition float_bv.cpp:233
static exprt abs(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:191
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:414
static exprt isnan(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:941
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.
Definition float_bv.cpp:926
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
static exprt subtract_exponents(const unbiased_floatt &src1, const unbiased_floatt &src2)
Subtracts the exponents.
Definition float_bv.cpp:498
exprt div(const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:737
exprt convert(const exprt &) const
Definition float_bv.cpp:19
static ieee_float_spect get_spec(const exprt &)
Definition float_bv.cpp:185
static exprt to_unsigned_integer(const exprt &src, std::size_t dest_width, const exprt &rm, const ieee_float_spect &)
Definition float_bv.cpp:357
static exprt negation(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:201
static exprt relation(const exprt &, relt rel, const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:826
static exprt isinf(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:909
static exprt sign_bit(const exprt &)
Definition float_bv.cpp:295
exprt mul(const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:686
static exprt fraction_all_zeros(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:267
static exprt exponent_all_zeros(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:258
static exprt is_equal(const exprt &, const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:211
static exprt to_signed_integer(const exprt &src, std::size_t dest_width, const exprt &rm, const ieee_float_spect &)
Definition float_bv.cpp:348
static exprt limit_distance(const exprt &dist, mp_integer limit)
Limits the shift distance.
Definition float_bv.cpp:663
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:2497
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:1061
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Definition std_expr.h:1228
Binary multiplication Associativity is not specified.
Definition std_expr.h:1107
The NIL expression.
Definition std_expr.h:3208
Boolean negation.
Definition std_expr.h:2454
Disequality.
Definition std_expr.h:1425
Boolean OR.
Definition std_expr.h:2270
The plus expression Associativity is not specified.
Definition std_expr.h:1002
Left shift.
Sign of an expression Predicate is true if _op is negative, false otherwise.
Definition std_expr.h:596
Fixed-width bit-vector with two's complement interpretation.
Semantic type conversion.
Definition std_expr.h:2073
The type of an expression, extends irept.
Definition type.h:29
The unary minus expression.
Definition std_expr.h:484
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 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:659
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:71
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:895
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition std_expr.h:2107
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition std_expr.h:426
const abs_exprt & to_abs_expr(const exprt &expr)
Cast an exprt to a abs_exprt.
Definition std_expr.h:466
const unary_minus_exprt & to_unary_minus_expr(const exprt &expr)
Cast an exprt to a unary_minus_exprt.
Definition std_expr.h:514
void get(const exprt &rm)
Definition float_bv.cpp:277
bool is_signed(const typet &t)
Convenience function – is the type signed?
Definition util.cpp:45