Home/Blog/Programming/Float vs. double in Java
Home/Blog/Programming/Float vs. double in Java

Float vs. double in Java

6 min read
Jun 05, 2023
content
The two representations of a floating-point number
Float vs. double in Java
Applications
Float
Double
Rounding errors
Using tolerance

Become a Software Engineer in Months, Not Years

From your first line of code, to your first day on the job — Educative has you covered. Join 2M+ developers learning in-demand programming skills.

A data type in a programming language classifies and represents data in a particular category that determines the type of values that can be stored in a variable. Different programming languages offer different data types including integers, floating-point numbers, characters, strings, and boolean numbers. In this blog, we’ll focus on floating-point numbers, more precisely on the differences between float and double.

Float vs. double: Let the competition begin
Float vs. double: Let the competition begin

The difference between float and double is in their precision. Float is a 32-bit single-precision floating-point type, whereas double is a 64-bit double-precision floating point.

However, there is more to learn about these data types, such as how are they stored? What are their use cases? And more importantly, are there any differences between float and double in Java?

The two representations of a floating-point number#

A number in a binary system consists of three parts:

  • Sign: Represents whether the number is positive or negative. It is usually represented by a bit, with 00 indicating a positive and 11 indicating a negative number.
  • Integer: Represents the whole number that appears before the decimal point.
  • Fraction: Represents the fraction that appears after the decimal point.
Representation of a number in a binary system
Representation of a number in a binary system

Fixed-point representation of a binary number uses a fixed number of bits for integer and fraction parts. Although convenient, fixed-point representation has limited precision and depends on the number of bits allocated to the fractional part.

Take an example of a 16-bit representation of 3.14163.1416 where we fix 77 bits for the integer and 88 bits for the fraction after the decimal point. The remaining 11 bit is reserved for the sign bit.

  • The sign bit will be 00 since the number is positive.
  • The integer 33 is converted into binary as 00000110000011.
  • The fraction 0.14160.1416 is converted into binary as 0010010000100100.

Another approach could be to fix the number of bits for the number and another set of bits to indicate the position of the decimal point within that number. This is called floating-point representation. We call the number without a decimal point a mantissa and the position of the decimal place an exponent. Floating-point representation is beneficial for applications in which the range of the values is large and the precision requirements are high.

Floating-point representation
Floating-point representation

Let’s continue the previous example and see how 3.14163.1416 is represented in a 16-bit floating-point representation. Considering 1010 bits for the mantissa and 55 for the exponent, the sign bit will be s=0s=0 since the number is positive. For the mantissa, we start with a binary equivalent of 3.1416=11.001001003.1416 = 11.00100100, which can be written as 11.00100100×2111.00100100 \times 2^1. Now the mantissa will be 11001001001100100100, and the exponent is a binary representation of 1=000011=00001.

Float vs. double in Java#

Having understood the concept of floating-point representation, it becomes easy to distinguish between float and double. As stated earlier in this blog, the primary contrast between float and double lies in their precision.

According to the IEEE 754 standard, a float is a 32-bit binary format, while double is a 64-bit binary format. The difference in the number of bits used for an exponent and a mantissa is summarized in the table below:

Float

Double

Sign

1

1

Exponent

8

11

Mantissa

23

52

Total

32

64

Now that we know the distribution of bits in float and double, we can determine the range of the data types — the maximum and minimum values that can be stored.

  • A float can store decimal numbers ranging from approximately ±1.5×1045\pm 1.5 \times 10^{-45} to ±3.4×1038\pm3.4 \times 10^{38}.
  • A double can store decimal numbers ranging from approximately ±5×10324\pm5 \times 10^{-324} to ±1.7×10308\pm1.7 \times 10^{308}.

Applications#

Let’s talk about some common applications in which float and double are used.

Float#

In general, applications that require less precision, are bound by processing power, or are limited by storage are suitable for using float instead of double. Some common examples of these applications are as follows:

  • Mobile devices: Storage is usually limited in mobile devices, making float an obvious choice. Float requires less memory and is more efficient at processing power than double.

  • Time-critical systems: Time-critical systems are often constrained by latency, making them an obvious use case for using float. A typical example is a self-driving car, in which faster processing and low processing latency are critical. Note that using float will make the processing faster at the expense of precision.

  • Graphics and audio processing: Since float has less precision, it’s also suitable for graphics and audio processing — applications in which it can provide enough precision.

Double#

Since double provides greater precision, the use cases are distinct compared to float. Here are some examples in which double would be suitable instead of float:

  • Financial calculations: Since precision is a key here, double is preferred in financial calculations to avoid rounding errors.

  • Scientific computing: Another use case for double is in scientific computations requiring accuracy. Examples include physics simulations, statistical simulations, climate modeling, etc.

  • Defense systems: A vital application in which precision is essential is defense systems. This is because in defense systems, like missile guiding systems, representing coordinates is critical and significantly impacts the accuracy of the results.

The diagram below briefly summarizes how to choose between a float and a double. Gauging the requirements of the underlying application can help you choose.

Spider diagram with precision, latency, and storage
Spider diagram with precision, latency, and storage

Rounding errors#

Arithmetic operations with floating-point numbers are not exact and can lead to rounding errors. These rounding errors can accumulate over time, leading to unexpected results. Let’s look at a simple example of adding a fraction=1/10 ten times in Java. Ideally, it should result in 1. Let’s see how floating-point arithmetic calculates it.

Java
public class Main {
public static void main(String[] args) {
float exp_result = 1.0f;
float fraction = 1.0f / 10.0f;
System.out.println();
float sum = 0.0f;
for (int i = 0; i < 10; i++) {
sum += fraction;
}
System.out.println("Expected Result: " + exp_result);
System.out.println("Actual Sum : " + sum);
if (exp_result == sum)
System.out.println("The expected result is equal to the calculated result");
else
System.out.println("The expected result is not equal to the calculated result");
}
}

Here, we append f or F to the value to declare a float on lines 3–4. We define a fraction on line 4 and add this fraction ten times to the variable sum on lines 9–11 in a for loop. Finally, the expected and actual results are compared on lines 16–19.

Note: The output will not change even if we change the variable types from float to double on lines 3–4. Go ahead and try it yourself!

The output shows that the actual result is different from the expected result. This is because the rounding errors accumulate over time.

Using tolerance#

Using appropriate tolerance values instead of exact comparisons when using floating-point numbers is essential. This avoids unexpected results when comparing floating-point numbers. The choice of tolerance depends on the application and the precision required. Let’s look at how to use tolerance values in our example.

Java
public class Main {
public static void main(String[] args) {
float exp_result = 1.0f;
float fraction = 1.0f / 10.0f;
float tolerance = 0.000001f;
System.out.println();
float sum = 0.0f;
for (int i = 0; i < 10; i++) {
sum += fraction;
}
System.out.println("Expected Result: " + exp_result);
System.out.println("Actual Sum : " + sum);
if (Math.abs(exp_result - sum) < tolerance)
System.out.println("The expected result is equal to the calculated result");
else
System.out.println("The expected result is not equal to the calculated result");
}
}

Here, we defined a variable tolerance on line 5 to compare the absolute difference between the actual and expected results on line 17. The output is now as expected.

We hope this experience was fun and helped you learn the differences between float and double in Java. If you’re looking to explore other data types and how they’re used in different programming languages, we recommend checking out the following courses on Educative:

Cover
Learn C++

This beginner-friendly course teaches C++ through a practical, hands-on approach. You’ll begin by learning how to communicate with the machine through input/output, simple calculations, and variables. Then, you’ll build programs to make decisions and repeat actions using conditionals and loops. As you progress, you’ll learn how to organize your code using functions, store data with arrays and vectors, and apply your knowledge by building mini projects like a number guessing game and a contact book. These exercises are designed to help you build confidence and reinforce your understanding. In the final section, you’ll build a complete project that combines all your skills in a creative, interactive program. Whether starting a tech career or just curious about coding, this course will give you a solid foundation in procedural C++ programming.

10hrs
Beginner
81 Playgrounds
15 Quizzes
Cover
Learn Java

You’ll start Java with the basics, such as printing messages, doing math, and working with user input, before exploring loops, conditionals, and object-oriented programming. Along the way, you’ll build real console apps, like games and menu systems, while learning how to structure your code using classes, methods, and objects. This course emphasizes hands-on learning and real-world modeling, making Java feel less intimidating and more intuitive. Whether you’re aiming to become an Android developer or backend engineer, or just want a solid foundation in programming, this course will help you write clean, structured code and confidently take your first step into software development. You need to know absolutely nothing about programming before your first lesson.

10hrs
Beginner
66 Playgrounds
14 Quizzes
Cover
Learn Python

This course uses an active learning approach to teach Python programming to beginners. You’ll interact with the code from the start, using everyday logic and fun challenges to build confidence. You will learn essential programming concepts through interactive examples and mini projects like input/output, decision-making, error handling, and simple logic. Whether new to coding or just starting with Python, this course provides the perfect foundation to develop your problem-solving skills and easily write your programs. More than anything else, this course aims to make you a lifelong learner and serve as a strong starting point for a successful career in computing. You don’t need any programming experience to begin.

10hrs
Beginner
103 Playgrounds
17 Quizzes

Written By:
Najeeb Ul Hassan

Free Resources