Videos
12 as a constant in java is an int.
The reason long l = 12 compiles is that it is automatically widened to a long.
EDIT: Regarding your comment, there is nothing wrong with automatic widening, use whatever makes your code clearer, but just be aware of what is going on when you do math on primitives. For example:
int i = 1213;
long l = 112321321L * i;
The long will have a very different value if you don't explicitly put that first number as a long because Java will treat it as integer math, and cause an overflow.
It doesn't make a difference if you use lower or upper case when declaring your floats .
...like "0.08F" for Ontario PST tax
If you are using these fields for currency, you should consider using BigDecimal instead. See this explanation and its related links from Sun for more detail.
The range of values that can be represented by a float or double is much larger than the range that can be represented by a long. Although one might lose significant digits when converting from a long to a float, it is still a "widening" operation because the range is wider.
From the Java Language Specification, §5.1.2:
A widening conversion of an int or a long value to float, or of a long value to double, may result in loss of precision - that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).
Note that a double can exactly represent every possible int value.
It is considered widening because the numbers that can be represented by a float is larger than numbers that can represented by long. Just because float uses 32 bit precision does not mean the numbers it can represent are limited to 2^32.
For instance the float (float)Long.MAX_VALUE+(float)Long.MAX_VALUE is larger than Long.MAX_VALUE, even though the float has less precision that the long.
I am learning Java, and am confuse on when to choose double or float for my real numbers or int. It feels like, it doesn’t matter because from my limited experience (with Java) both of them deliver the same results, but I don’t want to go further down the learning curve with Java and have a bad habit of using either messing up my code, and not having a clue as to why. So, when should you use float and double?
I was just trying to explain data type rankings and loss of precision to a class and realized that I was probably explaining it wrong. I typically only work with double and int's so this has never really occured to me.
The ranking from lowest to highest goes, byte < short < int < long < float < double. I typically just say it's because a byte can fit into a short(1 byte < 2 bytes) and an int can fit into a double(4 bytes < 8 bytes) but then it occured to me that a long is also 8 bytes yet it can fit into a float which is only 4 bytes.
I'm guessing it has something to do with the fact that floats are floating-point numbers and store 8 decimal places...So if the biggest long is something like 10 quintrillion(?) and that needs 8 bytes of memory to store it, how can a float can go to somethingx10^38 with decimal points still only need 4 bytes of memory to store it?
Converting long to float is a widening primitive conversion. Java allows it without error because...it's defined that way. From the link:
19 specific conversions on primitive types are called the widening primitive conversions:
bytetoshort,int,long,float, ordouble
shorttoint,long,float, ordouble
chartoint,long,float, ordouble
inttolong,float, ordouble
longtofloatordouble...
A widening primitive conversion from
inttofloat, or fromlongtofloat, or from long to double, may result in loss of precision - that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).
(My emphasis.)
Why allow it without requiring an explicit cast? In general, only James Gosling and others there at the time can answer that sort of question. For the rest of us, the answer is: Because that's what the specification says.
However, I'll note that even though precision is lost, overall magnitude is not, which I'd wager is why it's allowed. float can hold very large values imprecisely. So for instance:
class Demo {
public static void main(String[] args) {
long l = Long.MAX_VALUE;
float f = l;
System.out.println(l);
System.out.println(f);
}
}
Run that and you get:
9223372036854775807 9.223372E18
9.223372e18 is 9223372000000000000. Compare:
9223372036854775807 - the long value 9223372000000000000 - the float value
This is because float can sacrifice precision for range of value, because it stores a base value that it raises to an exponent. From Wikipedia's article on the IEEE-754 binary32 format (which is what Java's float is):
...an IEEE 754 32-bit base-2 floating-point variable has a maximum value of (2 − 2−23) × 2127 ≈ 3.402823 × 1038...
3.402823 × 1038 is:
340,282,300,000,000,000,000,000,000,000,000,000,000
...but the highest integer it can store such that you can add 1 and not lose precision is just 224-1 (16,777,215). It can store 16,777,216, but not 16,777,217. So 16,777,216 + 1 is still 16,777,216:
class Demo {
public static void main(String[] args) {
float f = 16_777_216f;
System.out.println(String.format("%8.0f", f)); // 16777216
System.out.println(String.format("%8.0f", f + 1)); // 16777216 (still)
}
}
That's because it's now storing the base value divided by 2 with an exponent of 2, so it can't store odd numbers anymore. It gets worse the higher you get, being able to only store multiples of 4, then of 8, then of 16, etc.
Contrast with the maxiumum value of a long, which is 263-1, which is "only":
9,223,372,036,854,775,807
But unlike float, it can represent each and every one of those integers precisely.
There is something like implicit typecasting. Javajava casts it automatically if you will not lose information. From float to long you could lose all behind the floating point so there will be no implicit cast because normally you do not want to lose this information.
The Wikipedia page on it is a good place to start.
To sum up:
floatis represented in 32 bits, with 1 sign bit, 8 bits of exponent, and 23 bits of the significand (or what follows from a scientific-notation number: 2.33728*1012; 33728 is the significand).doubleis represented in 64 bits, with 1 sign bit, 11 bits of exponent, and 52 bits of significand.
By default, Java uses double to represent its floating-point numerals (so a literal 3.14 is typed double). It's also the data type that will give you a much larger number range, so I would strongly encourage its use over float.
There may be certain libraries that actually force your usage of float, but in general - unless you can guarantee that your result will be small enough to fit in float's prescribed range, then it's best to opt with double.
If you require accuracy - for instance, you can't have a decimal value that is inaccurate (like 1/10 + 2/10), or you're doing anything with currency (for example, representing $10.33 in the system), then use a BigDecimal, which can support an arbitrary amount of precision and handle situations like that elegantly.
A float gives you approx. 6-7 decimal digits precision while a double gives you approx. 15-16. Also the range of numbers is larger for double.
A double needs 8 bytes of storage space while a float needs just 4 bytes.
LibGDX is a framework mostly used for game development.
In game development you usually have to do a whole lot of number crunching in real-time and any performance you can get matters. That's why game developers usually use float whenever float precision is good enough.
The size of the FPU registers in the CPU is not the only thing you need to consider in this case. In fact most of the heavy number crunching in game development is done by the GPU, and GPUs are usually optimized for floats, not doubles.
And then there is also:
- memory bus bandwidth (how fast you can shovel data between RAM, CPU and GPU)
- CPU cache (which makes the previous less necessary)
- RAM
- VRAM
which are all precious resources of which you get twice as much when you use 32bit float instead of 64bit double.
Floats use half as much memory as doubles.
They may have less precision than doubles, but many applications don't require precision. They have a larger range than any similarly-sized fixed point format. Therefore, they fill a niche that needs wide ranges of numbers but does not need high precision, and where memory usage is important. I've used them for large neural network systems in the past, for example.
Moving outside of Java, they're also widely used in 3D graphics, because many GPUs use them as their primary format - outside of very expensive NVIDIA Tesla / AMD FirePro devices, double-precision floating point is very slow on GPUs.
Sorry if this seems like a basic question, but I've been learning C over the past several weeks. In some of the tutorials I've been using, I've noticed some of the instructors just use int/float while others tend to default to double when declaring floating point variables.
Is there any sort of best practice in terms of deciding what size variable to use?