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)
FLOAT Made My Dollars Float Away - FLOAT vs DECIMAL in MySQL
Recently I got a task:
"Alter a table column from
FLOATtoDECIMAL(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:
| id | amount |
|---|---|
| 1 | 1000000.25 |
| 2 | 123456792.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.
FLOATstores numbers in binary (base 2).- But not every decimal number can be written exactly in binary.
Example:
- In decimal,
0.1is simple. - In binary,
0.1is infinite repeating:0.0001100110011… - So
FLOATcuts 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.99is stored as exactly123456789.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:
| id | amount |
|---|---|
| 1 | 1000000.25 |
| 2 | 123456789.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/DOUBLEfor 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 withALTER. 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. âś…