Fundamentals 7 min read

Why Float Is Dangerous for Money: Understanding Precision Errors and Safer Alternatives

This article explains why using float for monetary values leads to precision errors, demonstrates the binary representation of numbers like 6.6 and 1.3, and recommends safer alternatives such as integer cents or MySQL DECIMAL with practical Java examples.

Programmer DD
Programmer DD
Programmer DD
Why Float Is Dangerous for Money: Understanding Precision Errors and Safer Alternatives

Financial systems often use float for amounts, but floating‑point arithmetic is approximate, leading to rounding errors that can cause monetary loss.

Why float cannot store money accurately

Example: adding 6.6f and 1.3f yields 7.8999996 instead of 7.9.

public class FloatTest {
    public static void main(String[] args) {
        float f1 = 6.6f;
        float f2 = 1.3f;
        System.out.println(f1 + f2);
    }
}

Floats are stored in 32 bits: 1 sign bit, 8 exponent bits, 23 mantissa bits. The binary representation of 6.6 and 1.3 is repeating, so only the first 23 mantissa bits are kept, causing precision loss.

Binary conversion of 6.6 + 1.3

Integer part 6 → 110₂. Fractional part 0.6 is converted by repeatedly multiplying by 2, producing the repeating binary 0.10011001… . Thus 6.6 becomes 110.10011001… . After normalization the value is 1.1010011001 × 2². The exponent bias for float is 127, so the stored exponent is 129 (10000001₂). The mantissa stores the first 23 bits 10100110011001100110011, giving the final bit pattern 01000000110100110011001100110011.

Safer alternatives for monetary values

Store the amount in the smallest currency unit (e.g., cents) using an int or bigint column.

Use DECIMAL (or NUMERIC) in MySQL, which stores exact decimal values.

column_name decimal(P,D);

Example table:

CREATE TABLE test_decimal (
    id int NOT NULL,
    amount decimal(10,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

DAO interface:

@Repository
public interface TestDecimalDao {
    @Select("select * from test_decimal where id = #{id}")
    TestDecimal getTestDecimal(int id);
}

Test class demonstrates adding two decimal amounts and converting the result to float, which yields the expected 7.9.

public class TestDecimalDaoTest extends BaseTest {
    @Resource
    private TestDecimalDao testDecimalDao;

    @Test
    public void test() {
        TestDecimal d1 = testDecimalDao.getTestDecimal(1);
        TestDecimal d2 = testDecimalDao.getTestDecimal(2);
        BigDecimal result = d1.getAmount().add(d2.getAmount());
        System.out.println(result.floatValue());
    }
}

Drawbacks of DECIMAL

Consumes more storage space than floating‑point types for the same range.

Computation with DECIMAL is slower.

For most monetary applications, using an integer type (cents) or a bigint for large values avoids both floating‑point inaccuracies and the performance overhead of DECIMAL.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Decimalfloat precisionmoney storage
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.