0

After taking a look at code using the JBox-2D engine, it is clear that float declarations are used very often:

float x = 20.0f //<-- float

FixtureDef fixDef = new FixtureDef();
fixDef.shape = shape;
fixDef.density = 0.0f; //<-- float
fixDef.friction = 0.9f; //<-- float

I have tinkered around and found that the code complies properly when it is not indicated as a float. Thus, my question is:

Why must coders define values as floats in JBox-2D even though the variable it is stored in is already declared as a float?

ylun.ca
  • 2,504
  • 7
  • 26
  • 47
  • Are you referring to the `f` suffixes? – Jason C Mar 07 '14 at 05:26
  • How are you going to represent `0.9` as an integer? And how would it save memory, given that floats and ints are the same size? – user2357112 Mar 07 '14 at 05:29
  • `int32`s (standard integer size) and `float32` (standard float size) are the same size in bytes, so there's no memory savings. – Colin Basnett Mar 07 '14 at 05:29
  • A `float` and an `int` are both four bytes. Are you in a situation where you are running out of memory? – Jason C Mar 07 '14 at 05:30
  • @user2357112 what i was talking about earlier was actually a velocity declaration where it was an integer value of 45 or so. Float seems unnecessary. – ylun.ca Mar 07 '14 at 05:30
  • It's still going to get converted to a `float` if the object's fields are declared as `float`. Assigning an int to it instead of a float doesn't change anything. – user2357112 Mar 07 '14 at 05:32
  • @ylun I don't see anybody here making a statement that `int` is 64-bit. Also JBox-2D is a physics simulation engine. If you can make a reasonable physics simulation engine using only integer math, I suggest you publish a paper about it, because that would be some crazy stuff. If you're referring to the use of float constants instead of int constants; it doesn't really matter if they're being assigned to float variables. – Jason C Mar 07 '14 at 05:33
  • @JasonC Yes, the physics that I am attempting to recreate right now seems to stutter during a collision when two balls collide. I am using hard-body physics calculations. – ylun.ca Mar 07 '14 at 05:34
  • @user2357112 so then why is the indication `f` necessary? – ylun.ca Mar 07 '14 at 05:35
  • @ylun I don't know how hard you're tripping but you seem to be reading a completely different set of comments than the rest of us. I can't even begin to fit your last comments into this conversation. – Jason C Mar 07 '14 at 05:35
  • @JasonC from you: "Are you in a situation where you are running out of memory?". Now I ask the same question to you. – ylun.ca Mar 07 '14 at 05:36
  • @ylun I'm in a situation where conversations have context; and if a significant amount of comments have been made between the question that was asked and the question you are answering, you generally need to clarify what you are referring to, as responses are typically assumed to be to more recent comments. Good luck. – Jason C Mar 07 '14 at 05:37
  • @JasonC Thanks. As an honest suggestion, ask for clarification instead of giving an insult. – ylun.ca Mar 07 '14 at 05:38
  • @ylun I don't think he meant this as an insult, and this topic has become derailed in the course of about 5 minutes. Please stay on topic or this question will be closed. – Andrew Gies Mar 07 '14 at 05:47
  • @AndrewG My question remains, why is the indication of floating point, `f`, necessary? – ylun.ca Mar 07 '14 at 05:51
  • It's not "necessary", it's allowed by language. It may make the code more readable, or it may be mandated by a project's coding conventions, but these are external reasons or subjective. – hyde Mar 07 '14 at 06:43
  • Possible duplicate of [What is the 'f' used for in JBox-2d?](http://stackoverflow.com/questions/22180904/what-is-the-f-used-for-in-jbox-2d?rq=1) – Jason C Mar 07 '14 at 07:50

1 Answers1

3

If a number like 0.9 is going to be assigned to a float, the result will be more accurate in some cases if it is declared as 0.9f than if it is declared as 0.9, which is a double, and then cast from double to float. Declaring it as a float literal, with the "f", will never be worse than declaring it a double and casting to float.

There would be no precision loss on assigning an int literal to a float, compared to declaring the same value as a float literal, but if everything is being done in float, it is tidier to make all literals float, not just the non-integer ones. That way, the "f" is already there if the literal is later changed from integer to fraction.

================================================================================

The source of the problem is loss of information about the literal during conversion from decimal string to double. The following is an example of how this can happen.

Suppose a decimal fraction is very slightly greater than a double that is exactly half way between two adjacent floats, and the lower of the two floats is even (last bit is a zero).

The decimal fraction is closer to the larger of the two floats, and so rounds to it on direct conversion to float. If the conversion is done via double, the rounding to double loses that information. Double to float conversion uses round-half-even which maps a double half way between two adjacent floats to the even one, in this case the smaller one.

Here is a program demonstrating this:

import java.math.BigDecimal;

public class Test {
  public static void main(String[] args) {
    BigDecimal exactValue = new BigDecimal("1.5000000596046447753906251");
    System.out.println("Exact = " + exactValue);

    double d = 1.5000000596046447753906251;
    BigDecimal dValue = new BigDecimal(d);
    System.out.println("dValue = " + dValue);

    float f1 = 1.5000000596046447753906251f;
    BigDecimal f1Value = new BigDecimal(f1);
    System.out.println("f1Value = " + f1Value);

    float f2 = (float) 1.5000000596046447753906251;
    BigDecimal f2Value = new BigDecimal(f2);
    System.out.println("f2Value = " + f2Value);

    System.out.println("f1 error = "
        + exactValue.subtract(f1Value).abs());
    System.out.println("f2 error = "
        + exactValue.subtract(f2Value).abs());
  }
}

Output:

Exact = 1.5000000596046447753906251
dValue = 1.500000059604644775390625
f1Value = 1.50000011920928955078125
f2Value = 1.5
f1 error = 5.96046447753906249E-8
f2 error = 5.96046447753906251E-8

The absolute rounding error for f1, the result of direct conversion, is less than the absolute rounding error for f2, the result of conversion via double.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • +1 An example of a value that is more accurate with the `f` suffix is `float f1 = 1.01161128282547f`, giving a result different from (and more accurate than) `float f2 = 1.01161128282547;` – Pascal Cuoq Mar 07 '14 at 17:32
  • @ylun I have added an example program demonstrating the effect. – Patricia Shanahan Mar 19 '14 at 16:09
  • The phenomenon you describe would be analogous to rounding the value 123.4999996 to the nearest millionth before rounding to the nearest integer. Such a course of action yields 124, which is 0.5000004 larger than the specified value, whereas 123 would have been only 0.4999996 smaller than the specified value. If the value one wants is 123.4999996, both 123 and 124 are sufficiently inaccurate that the difference in accuracy between them is largely meaningless. The real reason for all the `f` suffixes is simply that Java squawks obnoxiously in their absence. – supercat Mar 20 '14 at 19:54