Skip to content

Refactor FloatingPointNumber#594

Open
daniel-raffler wants to merge 17 commits intomasterfrom
refactorFloatingPointNumber
Open

Refactor FloatingPointNumber#594
daniel-raffler wants to merge 17 commits intomasterfrom
refactorFloatingPointNumber

Conversation

@daniel-raffler
Copy link
Contributor

Hello,

after #513 the only way to create a FloatingPointNumber is to use FloatingPointNumber.of(String, FloatingPointType) or FloatingPointNumber.of(Sign, BigInteger, BigInteger, FloatingPointType). Both methods accept a FloatingPointType for the exponent and mantissa size. Versions of FloatingPointNumber.of(...) that accept mantissa and exponent size as separate integer arguments have been deprecated as it was not clear if the hidden bit should be included in the mantissa size, or not

However, when reading out the mantissa/exponent size of there is no way to get the FloatingPointType from an existing FoatingPointNumber. Instead, the sizes have to be accessed separately though FloatingPointNumber.getExponentSizeand FloatingPointNumber.getMantissaSizeWith(out)HiddenBit, which can be error prone:

public FloatingPointType getFloatingPointType(FloatingPointNumber pFloat) {
    return FormulaType.getFloatingPointTypeFromSizesWithoutHiddenBit(
        pFloat.getExponentSize(), pFloat.getMantissaSizeWithHiddenBit()); // there is a bug here
  }

In this PR we try to fix the issue by adding a new method FloatingPointNumber.getFloatingPointType() to get the FloatingPointType of a FloatingPointNumber. We also change the implementation, so that the FloatingPointType is stored directly when creating a new FloatingPointNumber, and add some additional sanity checks for the sizes

staticImports =
"org.sosy_lab.java_smt.api.FormulaType"
+ ".getFloatingPointTypeFromSizesWithoutHiddenBit")
@SuppressWarnings("InlineMeSuggester")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is inline me not working anymore? Sometimes its a little tricky to find the correct expression for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this one because the user is supposed to choose between getFloatingPointTypeFromSizesWithHiddenBit and getFloatingPointTypeFromSizesWithoutHiddenBit for the replacement

@Deprecated(
since = "2026.01, because mantissa arguments with/without sign bits can be misleading",
forRemoval = true)
@SuppressWarnings("InlineMeSuggester")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is inline me not working anymore? Sometimes its a little tricky to find the correct expression for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't working before 😉 These warnings showed up after I removed some redundant checks and the method was just a single expression. Now that some null checks have been added again the @SuppressWarnings isn't actually needed, and I removed it again

floatingPointType.getExponentSize(),
floatingPointType.getMantissaSizeWithoutHiddenBit());
Preconditions.checkArgument(
exponent.compareTo(BigInteger.ZERO) >= 0, "Exponent must not be negative");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use the BigInteger signum for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hint!

@Deprecated(
since = "2026.01, because mantissa arguments with/without sign bits can be misleading",
forRemoval = true)
@SuppressWarnings("InlineMeSuggester")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is inline me not working anymore? Sometimes its a little tricky to find the correct expression for it.

FloatingPointType.class,
FormulaType.getSinglePrecisionFloatingPointType(),
FormulaType.getDoublePrecisionFloatingPointType());
setDefault(FloatingPointType.class, getSinglePrecisionFloatingPointType());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we set this twice now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right. I've removed the setDefault

*/
public static FloatingPointType getFloatingPointTypeFromSizesWithHiddenBit(
int exponentSize, int mantissaSizeWithHiddenBit) {
checkArgument(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should stick to the standards wording here, in that it should be "greather than 1".

From:

 :sorts-description "All nullary sort symbols of the form 
 
    (_ FloatingPoint eb sb),

  where eb and sb are numerals greater than 1."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've updated the error messages

// size with hidden bit
var exponentSize = floatingPointType.getExponentSize();
var mantissaSizeWithoutHiddenBit = floatingPointType.getMantissaSizeWithoutHiddenBit();
Preconditions.checkArgument(exponentSize >= 0, "Exponent size must not be negative");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check this only once, and that location is clearly the type (so that we are failing early). This also applies to the other duplicate checks in this class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the extra check has been removed

Preconditions.checkArgument(
mantissa.compareTo(BigInteger.ZERO) >= 0, "Mantissa must not be negative");
Preconditions.checkArgument(
exponent.bitLength() <= floatingPointType.getExponentSize(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be a ==?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I think this should be fine. The exponent may have leading zeroes that are not counted by BigInteger.bitLength

@baierd
Copy link
Contributor

baierd commented Feb 10, 2026

@kfriedberger is this change/idea OK for you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants