-
Notifications
You must be signed in to change notification settings - Fork 53
Add IEEE-754 Floating Point to Bitvector Conversion Fallback #512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
6a91ebf
5c86496
06e365f
d00e534
bc5a5e3
6e6ec7e
f584f6b
9df8f21
105e7f2
4ec7107
97c1fe4
fdaabcc
3ecd133
52dbeb5
353b12c
6c554d0
9603aa6
1f09a65
43ee2a0
a27cc7e
de90781
b652b7f
11926f1
17227ac
31ffd68
3cc3a99
cd3a9c1
2fbe5bd
b789362
2fc661c
7b2b1de
dbacf94
2d27890
15efd20
ba26c93
9c72a5b
85a5b4e
edf028d
567e120
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
@AutoValue | ||
public abstract class FloatingPointNumber { | ||
|
||
// Mantissas do not include the sign bit | ||
public static final int SINGLE_PRECISION_EXPONENT_SIZE = 8; | ||
public static final int SINGLE_PRECISION_MANTISSA_SIZE = 23; | ||
public static final int DOUBLE_PRECISION_EXPONENT_SIZE = 11; | ||
|
@@ -80,8 +81,29 @@ public final boolean getSign() { | |
|
||
public abstract int getExponentSize(); | ||
|
||
/** | ||
* Returns the size of the mantissa (also called a coefficient or significant), excluding the sign | ||
* bit. | ||
*/ | ||
// TODO: mark as soon to be deprecated | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really want to remove this simple method? Is the documentation not sufficient? Please provide a replacement code snippet for inlining deprecated code. |
||
public abstract int getMantissaSize(); | ||
|
||
/** | ||
* Returns the size of the mantissa (also called a coefficient or significant), excluding the sign | ||
* bit. | ||
*/ | ||
public int getMantissaSizeWithoutSignBit() { | ||
return getMantissaSize(); | ||
} | ||
|
||
/** | ||
* Returns the size of the mantissa (also called a coefficient or significant), including the sign | ||
* bit. | ||
*/ | ||
public int getMantissaSizeWithSignBit() { | ||
return getMantissaSize() + 1; | ||
} | ||
|
||
/** | ||
* Get a floating-point number with the given sign, exponent, and mantissa. | ||
* | ||
|
@@ -92,7 +114,7 @@ public final boolean getSign() { | |
* @param mantissa the mantissa of the floating-point number, given as unsigned (not negative) | ||
* number without hidden bit | ||
* @param exponentSize the (maximum) size of the exponent in bits | ||
* @param mantissaSize the (maximum) size of the mantissa in bits | ||
* @param mantissaSize the (maximum) size of the mantissa in bits (excluding the sign bit) | ||
* @see #of(Sign, BigInteger, BigInteger, int, int) | ||
*/ | ||
@Deprecated( | ||
|
@@ -119,7 +141,7 @@ public static FloatingPointNumber of( | |
* @param mantissa the mantissa of the floating-point number, given as unsigned (not negative) | ||
* number without hidden bit | ||
* @param exponentSize the (maximum) size of the exponent in bits | ||
* @param mantissaSize the (maximum) size of the mantissa in bits | ||
* @param mantissaSize the (maximum) size of the mantissa in bits (excluding the sign bit) | ||
*/ | ||
public static FloatingPointNumber of( | ||
Sign sign, BigInteger exponent, BigInteger mantissa, int exponentSize, int mantissaSize) { | ||
|
@@ -136,7 +158,7 @@ public static FloatingPointNumber of( | |
* @param bits the bit-representation of the floating-point number, consisting of sign bit, | ||
* exponent (without bias) and mantissa (without hidden bit) in this exact ordering | ||
* @param exponentSize the size of the exponent in bits | ||
* @param mantissaSize the size of the mantissa in bits | ||
* @param mantissaSize the size of the mantissa in bits (excluding the sign bit) | ||
*/ | ||
public static FloatingPointNumber of(String bits, int exponentSize, int mantissaSize) { | ||
Preconditions.checkArgument(0 < exponentSize); | ||
|
@@ -159,24 +181,26 @@ public static FloatingPointNumber of(String bits, int exponentSize, int mantissa | |
|
||
/** | ||
* Returns true if this floating-point number is an IEEE-754-2008 single precision type with 32 | ||
* bits length consisting of an 8 bit exponent, a 23 bit mantissa and a single sign bit. | ||
* bits length consisting of an 8 bit exponent, a 24 bit mantissa (including the sign bit). | ||
* | ||
* @return true for IEEE-754 single precision type, false otherwise. | ||
*/ | ||
public boolean isIEEE754SinglePrecision() { | ||
// Mantissa does not include the sign bit | ||
return getExponentSize() == SINGLE_PRECISION_EXPONENT_SIZE | ||
&& getMantissaSize() == SINGLE_PRECISION_MANTISSA_SIZE; | ||
&& getMantissaSizeWithoutSignBit() == SINGLE_PRECISION_MANTISSA_SIZE; | ||
} | ||
|
||
/** | ||
* Returns true if this floating-point number is an IEEE-754-2008 double precision type with 64 | ||
* bits length consisting of an 11 bit exponent, a 52 bit mantissa and a single sign bit. | ||
* bits length consisting of an 11 bit exponent, a 53 bit mantissa (including the sign bit). | ||
* | ||
* @return true for IEEE-754 double precision type, false otherwise. | ||
*/ | ||
public boolean isIEEE754DoublePrecision() { | ||
// Mantissa does not include the sign bit | ||
return getExponentSize() == DOUBLE_PRECISION_EXPONENT_SIZE | ||
&& getMantissaSize() == DOUBLE_PRECISION_MANTISSA_SIZE; | ||
&& getMantissaSizeWithoutSignBit() == DOUBLE_PRECISION_MANTISSA_SIZE; | ||
} | ||
|
||
/** compute a representation as Java-based float value, if possible. */ | ||
|
@@ -204,18 +228,18 @@ public double doubleValue() { | |
} | ||
|
||
private BitSet getBits() { | ||
var mantissaSize = getMantissaSize(); | ||
var mantissaSizeWithoutSign = getMantissaSizeWithoutSignBit(); | ||
var exponentSize = getExponentSize(); | ||
var mantissa = getMantissa(); | ||
var exponent = getExponent(); | ||
var bits = new BitSet(1 + exponentSize + mantissaSize); | ||
var bits = new BitSet(exponentSize + mantissaSizeWithoutSign + 1); | ||
if (getMathSign().isNegative()) { | ||
bits.set(exponentSize + mantissaSize); // if negative, set first bit to 1 | ||
bits.set(exponentSize + mantissaSizeWithoutSign); // if negative, set first bit to 1 | ||
} | ||
for (int i = 0; i < exponentSize; i++) { | ||
bits.set(mantissaSize + i, exponent.testBit(i)); | ||
bits.set(mantissaSizeWithoutSign + i, exponent.testBit(i)); | ||
} | ||
for (int i = 0; i < mantissaSize; i++) { | ||
for (int i = 0; i < mantissaSizeWithoutSign; i++) { | ||
bits.set(i, mantissa.testBit(i)); | ||
} | ||
return bits; | ||
|
@@ -227,7 +251,7 @@ private BitSet getBits() { | |
*/ | ||
@Override | ||
public final String toString() { | ||
var length = 1 + getExponentSize() + getMantissaSize(); | ||
var length = getExponentSize() + getMantissaSizeWithSignBit(); | ||
var str = new StringBuilder(length); | ||
var bits = getBits(); | ||
for (int i = 0; i < length; i++) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -205,14 +205,61 @@ public String toSMTLIBString() { | |
} | ||
} | ||
|
||
public static FloatingPointType getFloatingPointType(int exponentSize, int mantissaSize) { | ||
return new FloatingPointType(exponentSize, mantissaSize); | ||
/** | ||
* Constructs a new IEEE-754 {@link FloatingPointType} with the given exponent and mantissa sizes. | ||
* The mantissa size is expected to not include the sign bit. | ||
* | ||
* @param exponentSize size of the exponent for the base of the floating-point | ||
* @param mantissaSizeWithoutSignBit size of the mantissa (also called a coefficient or | ||
* significant), excluding the sign bit. | ||
* @return the newly constructed {@link FloatingPointType}. | ||
*/ | ||
// TODO: mark as soon to be deprecated | ||
public static FloatingPointType getFloatingPointType( | ||
int exponentSize, int mantissaSizeWithoutSignBit) { | ||
return new FloatingPointType(exponentSize, mantissaSizeWithoutSignBit); | ||
} | ||
|
||
/** | ||
* Constructs a new IEEE-754 {@link FloatingPointType} with the given exponent and mantissa sizes. | ||
* The mantissa size is expected to not include the sign bit. | ||
* | ||
* @param exponentSize size of the exponent for the base of the floating-point | ||
* @param mantissaSizeWithoutSignBit size of the mantissa (also called a coefficient or | ||
* significant), excluding the sign bit. | ||
* @return the newly constructed {@link FloatingPointType}. | ||
*/ | ||
public static FloatingPointType getFloatingPointTypeWithoutSignBit( | ||
int exponentSize, int mantissaSizeWithoutSignBit) { | ||
return new FloatingPointType(exponentSize, mantissaSizeWithoutSignBit); | ||
} | ||
|
||
/** | ||
* Constructs a new IEEE-754 {@link FloatingPointType} with the given exponent and mantissa sizes. | ||
* The mantissa size is expected to not include the sign bit. | ||
* | ||
* @param exponentSize size of the exponent for the base of the floating-point | ||
* @param mantissaSizeWithSignBit size of the mantissa (also called a coefficient or significant), | ||
* including the sign bit. | ||
* @return the newly constructed {@link FloatingPointType}. | ||
*/ | ||
public static FloatingPointType getFloatingPointTypeWithSignBit( | ||
int exponentSize, int mantissaSizeWithSignBit) { | ||
return new FloatingPointType(exponentSize, mantissaSizeWithSignBit); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is the difference in this method to the one before? Both methods create the same object with the same parameters, even if they are named differently. |
||
} | ||
|
||
/** | ||
* @return single precision {@link FloatingPointType} with exponent sized 8, and mantissa sized 24 | ||
* (including the sign bit). | ||
*/ | ||
public static FloatingPointType getSinglePrecisionFloatingPointType() { | ||
return FloatingPointType.SINGLE_PRECISION_FP_TYPE; | ||
} | ||
|
||
/** | ||
* @return double precision {@link FloatingPointType} with exponent sized 11, and mantissa sized | ||
* 53 (including the sign bit). | ||
*/ | ||
public static FloatingPointType getDoublePrecisionFloatingPointType() { | ||
return FloatingPointType.DOUBLE_PRECISION_FP_TYPE; | ||
} | ||
|
@@ -226,6 +273,8 @@ public static final class FloatingPointType extends FormulaType<FloatingPointFor | |
new FloatingPointType(DOUBLE_PRECISION_EXPONENT_SIZE, DOUBLE_PRECISION_MANTISSA_SIZE); | ||
|
||
private final int exponentSize; | ||
// The SMTLib2 standard defines the mantissa size as including the sign bit. We do not include | ||
// it here though. | ||
private final int mantissaSize; | ||
|
||
private FloatingPointType(int pExponentSize, int pMantissaSize) { | ||
|
@@ -238,15 +287,40 @@ public boolean isFloatingPointType() { | |
return true; | ||
} | ||
|
||
/** Returns the size of the exponent. */ | ||
public int getExponentSize() { | ||
return exponentSize; | ||
} | ||
|
||
/** | ||
* Returns the size of the mantissa (also called a coefficient or significant), excluding the | ||
* sign bit. | ||
*/ | ||
// TODO: mark as soon to be deprecated | ||
public int getMantissaSize() { | ||
return mantissaSize; | ||
} | ||
|
||
/** Return the total size of a value of this type in bits. */ | ||
/** | ||
* Returns the size of the mantissa (also called a coefficient or significant), excluding the | ||
* sign bit. | ||
*/ | ||
public int getMantissaSizeWithoutSignBit() { | ||
return mantissaSize; | ||
} | ||
|
||
/** | ||
* Returns the size of the mantissa (also called a coefficient or significant), including the | ||
* sign bit. | ||
*/ | ||
public int getMantissaSizeWithSignBit() { | ||
return mantissaSize + 1; | ||
} | ||
|
||
/** | ||
* Return the total size of a value of this type in bits. Equal to exponent + mantissa | ||
* (including the sign bit). | ||
*/ | ||
public int getTotalSize() { | ||
return exponentSize + mantissaSize + 1; | ||
} | ||
|
@@ -270,12 +344,12 @@ public boolean equals(Object obj) { | |
|
||
@Override | ||
public String toString() { | ||
return "FloatingPoint<exp=" + exponentSize + ",mant=" + mantissaSize + ">"; | ||
return "FloatingPoint<exp=" + exponentSize + ",mant=" + getMantissaSizeWithSignBit() + ">"; | ||
} | ||
|
||
@Override | ||
public String toSMTLIBString() { | ||
return "(_ FloatingPoint " + exponentSize + " " + mantissaSize + ")"; | ||
return "(_ FloatingPoint " + exponentSize + " " + getMantissaSizeWithSignBit() + ")"; | ||
} | ||
} | ||
|
||
|
@@ -478,7 +552,7 @@ public static FormulaType<?> fromString(String t) { | |
} else if (t.startsWith("FloatingPoint<")) { | ||
// FloatingPoint<exp=11,mant=52> | ||
List<String> exman = Splitter.on(',').limit(2).splitToList(t.substring(14, t.length() - 1)); | ||
return FormulaType.getFloatingPointType( | ||
return FormulaType.getFloatingPointTypeWithoutSignBit( | ||
Integer.parseInt(exman.get(0).substring(4)), Integer.parseInt(exman.get(1).substring(5))); | ||
} else if (t.startsWith("Bitvector<")) { | ||
// Bitvector<32> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need these two methods?
The user already can access the FormulaType directly and extract exponentSize and mantissaSize from the returned FP-FormulaType.