Description
While using the API related to the floating-point theory in CPAchecker, we noticed several things that should be improved.
Boolean named "sign"
At least FloatingPointFormulaManager.makeNumber(BigInteger exponent, BigInteger mantissa, boolean signBit, FloatingPointType type)
, FloatingPointNumber.of(boolean sign, BigInteger exponent, BigInteger mantissa, int exponentSize, int mantissaSize)
, and FloatingPointNumber.getSign()
use a boolean named "sign". Out of these three places, only the latter documents whether true means positive or negative. Of course, the documentation should be completed such that this is documented everywhere.
However, in general I consider a boolean named "sign" to not be a good API, because it is not obvious what it means and it is too easy to make mistakes. Even already now we have proof for that: A developer who is highly experienced with both floats and JavaSMT made a mistake and mixed up the meaning of this boolean. If they did this, all other developers are even more likely to do so. So I would recommend to get rid of the name "sign" for a boolean in the public API completely. For the factory methods, it is unfortunately still easy to make a mistake even if the parameter is renamed, but at least it is better than now. For FloatingPointNumber.getSign()
I recommend to expose isNegative()
(and maybe isPositive()
) instead and make getSign()
@Deprecated
.
makeNumber(FloatingPointNumber)
The interface FloatingPointFormulaManager
is clearly missing a makeNumber(FloatingPointNumber)
method. Either this method can delegate to makeNumber(BigInteger exponent, BigInteger mantissa, boolean signBit, FloatingPointType type)
or vice versa in AbstractFloatingPointFormulaManager
, so solver implementations even do not need more effort to provide it.
Missing documentation of technicalities
There are some technical details about how floats are represented, e.g., whether the exponent is stored with or without bias, whether the significant has the hidden bit or not, and maybe more (I am not an expert in this area). None of the related JavaSMT methods documents which of these apply. This should be added, and (similar to the "sign" bit case) one should consider to make the APIs less error prone by for example moving this information into the name of methods and/or exposing less such difficult-to-use APIs publicly. Relevant are at least:
FloatingPointFormulaManager.makeNumber(BigInteger exponent, BigInteger mantissa, boolean signBit, FloatingPointType type)
FloatingPointNumber.of(boolean sign, BigInteger exponent, BigInteger mantissa, int exponentSize, int mantissaSize)
FloatingPointNumber.getExponent()
andFloatingPointNumber.getMantissa()
FloatingPointNumber.of(String bits, int exponentSize, int mantissaSize)
(which likely uses IEEE754 representation, so it could just document that)
Lack of connection between FloatingPointNumber
and FormulaType.FloatingPointType
While browsing through the code it seems surprising that there is no connection between FloatingPointNumber
and FormulaType.FloatingPointType
and that both of them independently store exponent and mantissa sizes. One might consider letting FloatingPointNumber
simply use a FloatingPointType
instance instead. This would likely simplify some code in FloatingPointNumber
, and potentially make it less tedious to copy around these values for user code as well. It also eliminates all potential bugs where someone mixes up the exponent and mantissa sizes, for example, which is easy because the compiler will not warn about it. (Luckily it seems that JavaSMT seems to always have exponent before mantissa in parameter lists, so it is consistent, but external code might not follow this pattern.)