0

The following is my code that works ::

public class AvgSpeed{
    public static void main(String[] args){
        double kph, km, hours, seconds, minutes, time;
        km = (1.6 * 24);
        hours = 1;
        minutes = 2/3f;
        seconds = 35/3600f;
        time = hours + minutes + seconds;
        kph = km/time;
        System.out.println(kph);
    }
}

If I remove the f's for minutes and seconds, it keeps printing out 38.4, which is not right. It should be some number close to 22.906

I don't even know the reason why I need to add the f, I did it on a whim. I thought declaring the two variables as a double was enough?

jww
  • 97,681
  • 90
  • 411
  • 885
user3278117
  • 95
  • 1
  • 8
  • In java when mathematics is performed, the expression is converted into one type e.g. 2/3 will be divides as an integer and result will get saved in minutes variable. Similarly for seconds (25/3600). Adding f (floating suffix) will hint the compiler to convert it to float while performing calculation. So, if you could try something like this 2.0/3.0 or 35.0/3600.0 or just adding it with one of the operand (like you did by adding f), the expression will result the expected outcome. – Kamran Khan Feb 06 '14 at 05:44

3 Answers3

1

In Java, 18.45 is a double data type which holds 64-bit. float data type can hold up to 32-bit only. Adding the extra f makes it a float (float literal).

See http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html for more detail

Kick
  • 4,823
  • 3
  • 22
  • 29
1

Declaring the variables as doubles doesn't make 2 or 3 a double. The conversion to double only happens after 2/3 is computed in integer arithmetic. To fix this, do the calculation in double arithmetic:

        minutes = 2.0/3;
        //         ^ double
        seconds = 35.0/3600;
        //         ^ double

The trailing f you appended made 3f and 3600f float literals. That's close to what you want, but not as good as doubles.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • How is it not as good as doubles? `seconds` is declared as a double so the result will be a double. Almost all processors treat floats as doubles when doing math with them, and the two literals in question don't have more significant digits than a float can handle. – nhgrif Feb 06 '14 at 05:42
  • So what did I essentially do when I declared everything as a double, but, not actually include doubles in my arithmetic? – user3278117 Feb 06 '14 at 05:43
  • @user3278117 You did integer math, then converted the result to a double. 35/3600 is 0, with a remainder of 35, so as an integer, that's just 0. And 0 converted to a double is 0.0. – nhgrif Feb 06 '14 at 05:44
  • Oh, so whenever I do arithmetic, if I want a result that won't be rounded, I should always append a .0 to it AND make sure that the variable was declared as a double? What happens if i declared say, int seconds = 36.0/3600? – user3278117 Feb 06 '14 at 05:45
  • @user3278117 The same thing that would happen if you did `double doubleSeconds = 36.0/3600; int seconds = doubleSeconds;` The value of `36.0/3600` would be calculated using floating point math and then converted to an `int`. `seconds` would be `0`. – nhgrif Feb 06 '14 at 05:47
  • 1
    @nhgrif Here's why a `float` isn't as good as a `double`: The expression is computed based on the types of the arguments only. The type of `seconds` doesn't matter. If you say `35/3600f`, both operands are promoted to `float` (JLS 5.6.2). The type of the resulting expression is the type of its promoted operands (JLS 15.17), i.e. `float`. This means that even if 35/3600 is computed as a `double`, the result type will be a `float`, which I think means some mantissa bits will be lost. They don't come back when the `float` is re-cast to the `double`. I'm not sure, though... – ajb Feb 06 '14 at 05:52
  • @nhgrif: `System.out.println(2/3f == 2.0/3);` prints `false` when I try it. – user2357112 Feb 06 '14 at 05:56
  • @user3278117, @nhgrif: The result of `int seconds = 36.0/3600` is an error at compile time. `36.0/3600` is a `double`, and Java will not let you convert a `double` to an `int` without a cast. – ajb Feb 06 '14 at 05:56
  • 1
    2.0/3.0 is 0.66666666666666662965923251249478198587894439697265625. 2f/3f is 0.666666686534881591796875. Doing the calculation in double results in a much better approximation to 0.666666666..., although either is much better than 2/3, which is 0. – Patricia Shanahan Feb 06 '14 at 07:16
0
double minutes;
minutes = 2/3;

This code takes two integers, divides them, converts the result to a double and stores it in minutes. In that order. To get the result you want you need to convert to doubles before the division happens. You managed to do this by adding f (use d for double, btw). You could also do it with minutes = 2.0/3.0;

pgs
  • 13,385
  • 2
  • 25
  • 17