Skip to content

Commit 8f848b6

Browse files
committed
Floating-point normalization must not overflow
We need to extend the exponent to compute a new exponent without overflow; subsequent denormalization and rounding will ensure the exponent fits into the target format. Fixes: #7616
1 parent 5cd2d1b commit 8f848b6

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <assert.h>
2+
3+
int main()
4+
{
5+
#if 0
6+
// examples of constants that previously exhibited wrong behaviour
7+
union U
8+
{
9+
double d;
10+
uint64_t b;
11+
};
12+
union U u = {
13+
.b = 0b0000000000000011111111111111111111111110000001000000000000000000};
14+
union U u2 = {
15+
.b = 0b0000000000000000000000000000001111111111111111111111111000000000};
16+
double d = u.d;
17+
#else
18+
double d;
19+
#endif
20+
float f;
21+
if(d > 0.0 && d < 1.0)
22+
{
23+
f = d;
24+
assert(f <= 1.0f);
25+
}
26+
return 0;
27+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/solvers/floatbv/float_utils.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -792,8 +792,9 @@ void float_utilst::normalization_shift(bvt &fraction, bvt &exponent)
792792
PRECONDITION(!fraction.empty());
793793
std::size_t depth = address_bits(fraction.size() - 1);
794794

795-
if(exponent.size()<depth)
796-
exponent=bv_utils.sign_extension(exponent, depth);
795+
// sign-extend to ensure the arithmetic below cannot result in overflow/underflow
796+
exponent =
797+
bv_utils.sign_extension(exponent, std::max(depth, exponent.size() + 1));
797798

798799
bvt exponent_delta=bv_utils.zeros(exponent.size());
799800

0 commit comments

Comments
 (0)