Skip to content

Instantly share code, notes, and snippets.

@theonewolf
Forked from anonymous/README.md
Last active January 1, 2016 21:19
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 theonewolf/8202419 to your computer and use it in GitHub Desktop.
Save theonewolf/8202419 to your computer and use it in GitHub Desktop.
  • Execute Java with something like: javac Test.java; java Test
  • The comments are valuable feedback in interpreting lines of Java code and understanding what they do
  • The output of the program discusses why certain things are occurring, and offers ideas on answering the question
  • My (attempt at a) final answer: This is just a defensive programming technique, meant for programmers. It doesn't technically do anything, and is just a "best practice" convention to follow when assigning values to float-typed variables
public class Test {
public static void main(String[] args) {
int I = 0;
long count = 0;
float N = -39250; /* Coercing integer to float and assignment */
/* The above line is _valid_ Java; however, the coercion might not do what you _think_ it does. */
/* In this case, trickily, I think this is _valid_ and _works as designed_ code, so no problem. */
System.out.println("N = -39250 == " + N);
N = -39250.0f; /* Assigning float to float */
System.out.println("N = -39250.0f == " + N);
N = 39250.2f; /* Assigning float to float --> specify 'f' so as not to automatically be a double and raise a type checker error at compile-time */
System.out.println("N = -39250.2f == " + N);
System.out.println("\n\n-- By convention, always declaring with '.0f' is _safer_ (defensive programming) --");
System.out.println("-- Although, it is not always necessary --");
System.out.println("-- For example, certain floats do not exist as integers: -0.0, NaN --");
N = -0;
System.out.println("*** N = -0 == " + N);
N = -0f;
System.out.println("N = -0f == " + N);
N = Float.NaN;
System.out.println("N = Float.NaN == " + N);
I = (int) N;
System.out.println("*** I = (int) N == " + I);
System.out.println("\n\n-- Precision with floats is also odd. --");
N = -39250;
System.out.println("N = -39250 == " + N);
I = (int) N;
System.out.println("I = (int) N == " + I);
System.out.println("N == -39250 == " + (N == -39250));
System.out.println("I == -39250 == " + (I == -39250));
System.out.println("N == -39250.0 == " + (N == -39250.0));
System.out.println("N == I == " + (N == I));
N = -39250.0f;
System.out.println("N = -39250.0f == " + N);
I = -39250;
System.out.println("I = -39250 == " + I);
System.out.println("N == -39250 == " + (N == -39250));
System.out.println("I == -39250 == " + (I == -39250));
System.out.println("N == -39250.0 == " + (N == -39250.0));
System.out.println("N == I == " + (N == I));
System.out.println("\n\n-- -39250 seems safe, what about all the other possible integer values? --");
float D = 0.0f;
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
D = (float) i;
if (i != (int) (D)) {
count++;
}
}
System.out.println("*** " + count + " integers are unrepresentable with full precision as floats");
System.out.println("\n\n-- Let's investigate one of these 'unrepresentable' integers. --");
System.out.println("-- In this case, we choose a rather small 16,777,217 (representable in _slightly_ more than 24 bits)! --");
System.out.println("-- Recall that IEEE-754 floats have 24 bits of precision, whereas Java int's have 32. -- ");
I = 16777217;
N = 16777217;
System.out.println("I = 16777217 == " + I);
System.out.println("N = 16777217 == " + N);
System.out.println("N == 16777217 == " + (N == 16777217));
System.out.println("I == 16777217 == " + (I == 16777217));
System.out.println("N == 16777217.0 == " + (N == 16777217.0));
System.out.println("N == I == " + (N == I));
System.out.println("*** (int) N == " + (int) N);
System.out.println("*** (int) N == I == " + ((int) N == I));
System.out.println("\n\n-- Okay, can .0f help? --");
System.out.println("-- No, no it can't. I conclude the .0f is more defensive for a programmer reading ---");
System.out.println("-- The programmer should think, be careful, and check values with f appended. --");
System.out.println("-- Because floats have less precision than ints, there are ints unrepresentable as floats. --");
System.out.println("-- As well as special floats that look like ints, parse as ints, but can not be represented as integers (-0) --");
N = 16777217.0f;
System.out.println("N = 16777217.0f == " + N);
System.out.println("N == 16777217 == " + (N == 16777217));
System.out.println("I == 16777217 == " + (I == 16777217));
System.out.println("N == 16777217.0 == " + (N == 16777217.0));
System.out.println("N == I == " + (N == I));
System.out.println("*** (int) N == " + (int) N);
System.out.println("*** (int) N == I == " + ((int) N == I));
return;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment