FLOAT Made My Dollars Float Away - FLOAT vs DECIMAL in MySQL 💸

FLOAT Made My Dollars Float Away - FLOAT vs DECIMAL in MySQL 💸

Recently I got a task Alter a table column from `FLOAT` to `DECIMAL(10,2)

19th Sep 2025

FLOAT Made My Dollars Float Away - FLOAT vs DECIMAL in MySQL

Recently I got a task:

"Alter a table column from FLOAT to DECIMAL(10,2)"

I thought: "Pff, easy task. Just run an ALTER TABLE and done. Why is this even a ticket?"

But then I read the description. Turns out, FLOAT was causing data loss, and I needed to convert it without losing data.

That’s when I realized: this isn’t just about one query. It’s about how FLOAT silently eats your money in MySQL.

Why FLOAT is a Problem

FLOAT in MySQL is a binary floating-point type. It doesn’t store exact values — only approximations.

That’s fine for rocket science 🚀 or graphics rendering 🎮, but for money where every cent matters? Disaster.

Think of FLOAT as a leaky bucket. You pour in $1,000,000.25… and it gives you back $999,999.94.

Not funny when it’s your salary.

Example of Data Loss

CREATE TABLE money_float (
    id INT AUTO_INCREMENT PRIMARY KEY,
    amount FLOAT
);

INSERT INTO money_float (amount) VALUES (1000000.25), (123456789.99);

SELECT * FROM money_float;

Result:

idamount
11000000.25
2123456792.00

We inserted 123456789.99, but got back 123456792.00. The bigger the number, the worse the corruption.

But Why Does FLOAT Lose Data?

Here’s the fun part. Let’s make it simple.

  • FLOAT stores numbers in binary (base 2).
  • But not every decimal number can be written exactly in binary.

Example:

  • In decimal, 0.1 is simple.
  • In binary, 0.1 is infinite repeating: 0.0001100110011…
  • So FLOAT cuts it off at some point and stores an approximation.

That’s why when you do:

INSERT INTO money_float (amount) VALUES (0.1);
SELECT amount FROM money_float;

You might see something like 0.10000000149.

Now imagine this tiny error repeated in millions of dollars. Errors pile up, and suddenly your 9-digit amount looks… off.

DECIMAL to the Rescue

DECIMAL stores numbers differently:

  • Instead of binary approximation, it stores exact digits as strings internally.
  • That means 123456789.99 is stored as exactly 123456789.99.
CREATE TABLE money_decimal (
    id INT AUTO_INCREMENT PRIMARY KEY,
    amount DECIMAL(15,2)
);

INSERT INTO money_decimal (amount) VALUES (1000000.25), (123456789.99);

SELECT * FROM money_decimal;

Result:

idamount
11000000.25
2123456789.99

Perfect. ✅ No rounding surprises.

Why ALTER Won’t Save You

Here’s the trap I fell into:

ALTER TABLE money_float MODIFY amount DECIMAL(15,2);

You’d think this fixes it, right? Nope. ❌

The data was already corrupted when it was first inserted as FLOAT. ALTER just moves the already-broken value into DECIMAL.

Garbage in → garbage out.

Visual: FLOAT vs DECIMAL

FLOAT (approximation in binary):
123456789.99  --->  123456792.00 💀

DECIMAL (exact digits):
123456789.99  --->  123456789.99 ✅

Lessons Learned

  • Never use FLOAT/DOUBLE for money.
  • Always use DECIMAL(precision, scale) (e.g., DECIMAL(15,2)).
  • If your table already has money in FLOAT, you cannot fix the lost precision with ALTER. You’ll need to re-import or clean it at the source.

Final Thought

Using FLOAT for money is like paying your salary in Monopoly money. 🎲💵 It looks okay until you try to spend it — then you realize it’s worthless.

Stick with DECIMAL, and your dollars will stay safe. ✅