Floating-Point Precision (0.1 + 0.2)

easy Programming Basics

Problem

Read three decimal numbers x, y and z. Print two lines. The first line is exact: true if x + y == z (compared with ==), else exact: false. The second line is close: true if the difference between x + y and z is less than 0.000000001, else close: false. Example: 0.1 0.2 0.3 gives exact: false and close: true.

Constraints

  • Inputs are decimal numbers with at most 15 significant digits

Examples

Input

0.1 0.2 0.3

Output

exact: false
close: true

Solutions

Best approachTime O(1)Space O(1)

Computers store decimals in binary. Numbers like 0.1 have no exact binary form, like 1/3 has no exact decimal form. So never compare decimals with ==. Compare with a small tolerance.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Compare a decimal sum with a target.
 * Input   : Three decimal numbers x, y, z.
 * Output  : Two lines: exact and close.
 * Approach: Compare with a small tolerance.
 * Time    : O(1)
 * Space   : O(1)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double x = Double.parseDouble(scanner.next());
        double y = Double.parseDouble(scanner.next());
        double z = Double.parseDouble(scanner.next());

        // Step 1: Add the two numbers. The result can have a tiny error.
        double sum = x + y;

        // Step 2: Compare with == . This is exact, so tiny errors make it false.
        boolean exact = (sum == z);

        // Step 3: Compare with a tolerance. This is the correct way for decimals.
        boolean close = Math.abs(sum - z) < 1e-9;

        // Step 4: Print both answers.
        System.out.println("exact: " + exact);
        System.out.println("close: " + close);
    }
}
Hints (2)
  1. Is 0.1 exactly stored in binary?
  2. How can we say two decimals are almost equal?