Skip to content

Instantly share code, notes, and snippets.

@stanio
Created October 3, 2023 16:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stanio/8e31e9f8a4641e87d22ca308ad597c93 to your computer and use it in GitHub Desktop.
Save stanio/8e31e9f8a4641e87d22ca308ad597c93 to your computer and use it in GitHub Desktop.
Debugging float bits
//package ;
import java.math.BigDecimal;
import java.util.Locale;
public class FloatTest {
// FloatConsts.SIGNIFICAND_WIDTH - 1
static final int SIGNIF_SIZE = 23;
static final int EXP_SIZE = 8;
static final int EXP_MASK = 0xFF << SIGNIF_SIZE;
public static void main(String[] args) throws Exception {
float[] nums = { Float.POSITIVE_INFINITY,
Float.NEGATIVE_INFINITY,
Float.NaN,
0f,
-0f,
3.5f,
-3.25f,
3.125f,
Float.MIN_VALUE,
Float.MIN_NORMAL,
Float.MAX_VALUE };
for (float n : nums) debugFloat(n);
System.out.println();
System.out.println("*** Some exact binary == decimal floats:");
final int seven = 0b0_10000001_11000000000000000000000;
debugFloat(Float.intBitsToFloat(seven));
// 2 (+1 implied) bits for the integral
// 7 value: 11xxxxxxxxxxxxxxxxxxxxx
final int integSize = 2;
for (int b = 1; b < 16; b += 1) {
int fractionBits = Integer
.reverse(b) >>> (Float.SIZE - SIGNIF_SIZE + integSize);
debugFloat(Float
.intBitsToFloat(seven | fractionBits));
}
System.out.println();
System.out.println("---");
debugFloat(Float.intBitsToFloat(0b0_01101010_00000000000000000000000));
debugFloat(Float.intBitsToFloat(0b0_01101001_00000000000000000000000));
debugFloat(Float.intBitsToFloat(0b0_01101000_00000000000000000000000));
debugFloat(Float.intBitsToFloat(0b0_01100111_00000000000000000000000));
debugFloat(Float.intBitsToFloat(0b0_01010010_00000000000000000000000));
debugFloat(Float.intBitsToFloat(0b0_01010001_00000000000000000000000));
debugFloat(Float.intBitsToFloat(0b0_01010000_00000000000000000000000));
debugFloat(Float.intBitsToFloat(0b0_01001111_00000000000000000000000));
System.out.println("---");
debugFloat(0.3f);
debugFloat(0.4f);
debugFloat(0.5f);
debugFloat(0.7f);
debugFloat(0.3f + 0.4f);
System.out.println("---");
debugFloat(Float.intBitsToFloat(0b0_01111110_11111111111111111111000));
debugFloat(Float.intBitsToFloat(0b0_01111110_11111111111111111111100));
debugFloat(Float.intBitsToFloat(0b0_01111110_11111111111111111111110));
debugFloat(Float.intBitsToFloat(0b0_01111110_11111111111111111111111));
debugFloat(1f);
debugFloat(Float.intBitsToFloat(0b0_01111111_00000000000000000000001));
debugFloat(Float.intBitsToFloat(0b0_01111111_00000000000000000000010));
debugFloat(Float.intBitsToFloat(0b0_01111111_00000000000000000000011));
debugFloat(Float.intBitsToFloat(0b0_01111111_00000000000000000000100));
debugFloat(Float.intBitsToFloat(0b0_01111111_00000000000000000000101));
debugFloat(Float.intBitsToFloat(0b0_01111111_00000000000000000000110));
debugFloat(Float.intBitsToFloat(0b0_01111111_00000000000000000000111));
System.out.println("---");
debugFloat(Float.intBitsToFloat(0b0_01111111_00000000000000000000001));
debugFloat(Float.intBitsToFloat(0b0_10000000_00000000000000000000001));
debugFloat(Float.intBitsToFloat(0b0_10000001_00000000000000000000001));
debugFloat(Float.intBitsToFloat(0b0_10000010_00000000000000000000001));
debugFloat(Float.intBitsToFloat(0b0_10000011_00000000000000000000001));
debugFloat(Float.intBitsToFloat(0b0_10000100_00000000000000000000001));
debugFloat(Float.intBitsToFloat(0b0_10000101_00000000000000000000001));
debugFloat(Float.intBitsToFloat(0b0_10000110_00000000000000000000001));
debugFloat(Float.intBitsToFloat(0b0_10000111_00000000000000000000001));
System.out.println("---");
debugFloat(Float.MAX_VALUE);
debugFloat(Float.MAX_VALUE - 1_234_567f);
float bigFloat = BigDecimal.valueOf(Float.MAX_VALUE / 2).floatValue();
debugFloat(bigFloat);
System.out.append(floatString(bigFloat))
.append(" + ").print(1_234_567f);
System.out.append(" =? ").append(floatString(bigFloat))
.append(" (").print(bigFloat + 1_234_567f == bigFloat);
System.out.println("! 🤪)");
}
static void debugFloat(float num) {
int floatBits = Float.floatToRawIntBits(num);
char sign = (floatBits < 0) ? '-' : ' ';
int exp = Math.getExponent(num);
String binStr = binaryString(floatBits);
String expBits = binStr.substring(1, 1 + EXP_SIZE);
String significand = binStr.substring(1 + EXP_SIZE);
char impliedBit = exp >= Float.MIN_EXPONENT
? (Float.isFinite(num) ? '1' : '*')
: '0';
String decimal = Float.isFinite(num)
&& Math.abs(exp) / 2 < 40
? new BigDecimal(Float.toString(num)).toPlainString()
: floatString(num);
System.out.printf(Locale.ROOT, "Bin: %s(%s).%sE%+d[%s], Dec: %s%n",
sign, impliedBit, significand, exp, expBits, decimal);
}
static String floatString(float num) {
return Float.toString(num).replaceFirst("E(\\d)", "E+$1");
}
static String binaryString(int num) {
return String.format("%32s", Integer.toBinaryString(num))
.replace(' ', '0');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment