Skip to content

Commit b4210a9

Browse files
committed
improve documentation for FP operations and rounding.
1 parent 2dd76da commit b4210a9

File tree

2 files changed

+73
-3
lines changed

2 files changed

+73
-3
lines changed

src/org/sosy_lab/java_smt/api/FloatingPointFormulaManager.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,75 @@
1919
* <p>Most operations are overloaded: there is an option of either using the default rounding mode
2020
* (set via the option {@code solver.floatingPointRoundingMode}), or providing the rounding mode
2121
* explicitly.
22+
*
23+
* <p>If the result of an operation can not be exactly represented by the available floating-point
24+
* type, i.e., the given precision is insufficient, the result is rounded to the nearest possible
25+
* floating-point representation, depending on the given rounding mode.
26+
*
27+
* <p>Example: If the input number is too large to be represented as a floating point with the given
28+
* type, it will be converted to positive infinity (+inf) or negative infinity (-inf). If the input
29+
* number is too small to be represented with the given type (closer to zero than the smallest
30+
* possible floating-point number), it will be converted to zero, with the sign preserved.
2231
*/
2332
public interface FloatingPointFormulaManager {
2433

34+
/**
35+
* Creates a floating point formula representing the given double value with the specified type.
36+
*/
2537
FloatingPointFormula makeNumber(double n, FloatingPointType type);
2638

39+
/**
40+
* Creates a floating point formula representing the given double value with the specified type
41+
* and rounding mode.
42+
*/
2743
FloatingPointFormula makeNumber(
2844
double n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode);
2945

46+
/**
47+
* Creates a floating point formula representing the given BigDecimal value with the specified
48+
* type.
49+
*/
3050
FloatingPointFormula makeNumber(BigDecimal n, FloatingPointType type);
3151

52+
/**
53+
* Creates a floating point formula representing the given BigDecimal value with the specified
54+
* type and rounding mode.
55+
*/
3256
FloatingPointFormula makeNumber(
3357
BigDecimal n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode);
3458

59+
/**
60+
* Creates a floating point formula representing the given string value with the specified type.
61+
*/
3562
FloatingPointFormula makeNumber(String n, FloatingPointType type);
3663

64+
/**
65+
* Creates a floating point formula representing the given string value with the specified type
66+
* and rounding mode.
67+
*/
3768
FloatingPointFormula makeNumber(
3869
String n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode);
3970

71+
/**
72+
* Creates a floating point formula representing the given Rational value with the specified type.
73+
*/
4074
FloatingPointFormula makeNumber(Rational n, FloatingPointType type);
4175

76+
/**
77+
* Creates a floating point formula representing the given Rational value with the specified type
78+
* and rounding mode.
79+
*/
4280
FloatingPointFormula makeNumber(
4381
Rational n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode);
4482

83+
/**
84+
* Creates a floating point formula from the given exponent, mantissa, and sign bit with the
85+
* specified type.
86+
*
87+
* @param exponent the exponent part of the floating point number
88+
* @param mantissa the mantissa part of the floating point number
89+
* @param signBit the sign bit of the floating point number, e.g., true for negative numbers
90+
*/
4591
FloatingPointFormula makeNumber(
4692
BigInteger exponent, BigInteger mantissa, boolean signBit, FloatingPointType type);
4793

src/org/sosy_lab/java_smt/test/FloatingPointFormulaManagerTest.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class FloatingPointFormulaManagerTest
5555
private FloatingPointFormula negInf;
5656
private FloatingPointFormula zero;
5757
private FloatingPointFormula one;
58+
private FloatingPointFormula negZero;
5859

5960
@Before
6061
public void init() {
@@ -66,6 +67,7 @@ public void init() {
6667
posInf = fpmgr.makePlusInfinity(singlePrecType);
6768
negInf = fpmgr.makeMinusInfinity(singlePrecType);
6869
zero = fpmgr.makeNumber(0.0, singlePrecType);
70+
negZero = fpmgr.makeNumber(-0.0, singlePrecType);
6971
one = fpmgr.makeNumber(1.0, singlePrecType);
7072
}
7173

@@ -131,8 +133,7 @@ public void parser() throws SolverException, InterruptedException {
131133
public void negativeZeroDivision() throws SolverException, InterruptedException {
132134
BooleanFormula formula =
133135
fpmgr.equalWithFPSemantics(
134-
fpmgr.divide(
135-
one, fpmgr.makeNumber(-0.0, singlePrecType), FloatingPointRoundingMode.TOWARD_ZERO),
136+
fpmgr.divide(one, negZero, FloatingPointRoundingMode.TOWARD_ZERO),
136137
fpmgr.makeMinusInfinity(singlePrecType));
137138
assertThatFormula(formula).isSatisfiable();
138139
assertThatFormula(bmgr.not(formula)).isUnsatisfiable();
@@ -267,8 +268,8 @@ public void specialValueFunctions() throws SolverException, InterruptedException
267268
assertThatFormula(fpmgr.isSubnormal(zero)).isUnsatisfiable();
268269
assertThatFormula(fpmgr.isSubnormal(zero)).isUnsatisfiable();
269270

270-
FloatingPointFormula negZero = fpmgr.makeNumber(-0.0, singlePrecType);
271271
assertThatFormula(fpmgr.isZero(negZero)).isTautological();
272+
assertThatFormula(fpmgr.equalWithFPSemantics(zero, negZero)).isTautological();
272273
assertThatFormula(fpmgr.isSubnormal(negZero)).isUnsatisfiable();
273274
assertThatFormula(fpmgr.isSubnormal(negZero)).isUnsatisfiable();
274275

@@ -1056,4 +1057,27 @@ public void fpFrom64BitPattern() throws SolverException, InterruptedException {
10561057
assertEqualsAsFormula(fpFromBv, fp);
10571058
}
10581059
}
1060+
1061+
@Test
1062+
public void fpFromNumberIntoTooNarrowType() throws SolverException, InterruptedException {
1063+
// near zero rounds to zero, if precision is too narrow
1064+
for (double nearZero : new double[] {Double.MIN_VALUE, Float.MIN_VALUE / 2d}) {
1065+
assertThatFormula(
1066+
fpmgr.equalWithFPSemantics(zero, fpmgr.makeNumber(nearZero, singlePrecType)))
1067+
.isTautological();
1068+
assertThatFormula(
1069+
fpmgr.equalWithFPSemantics(negZero, fpmgr.makeNumber(-nearZero, singlePrecType)))
1070+
.isTautological();
1071+
}
1072+
1073+
// near infinity rounds to infinity, if precision is too narrow
1074+
for (double nearInf : new double[] {Double.MAX_VALUE, Float.MAX_VALUE * 2d}) {
1075+
assertThatFormula(
1076+
fpmgr.equalWithFPSemantics(posInf, fpmgr.makeNumber(nearInf, singlePrecType)))
1077+
.isTautological();
1078+
assertThatFormula(
1079+
fpmgr.equalWithFPSemantics(negInf, fpmgr.makeNumber(-nearInf, singlePrecType)))
1080+
.isTautological();
1081+
}
1082+
}
10591083
}

0 commit comments

Comments
 (0)