---
title: FLOAT Made My Dollars Float Away - FLOAT vs DECIMAL in MySQL 💸
date: 19th Sep 2025
description: Recently I got a task Alter a table column from `FLOAT` to `DECIMAL(10,2)
image: /blogs-img/blog8.png
alt: FLOAT Made My Dollars Float Away - FLOAT vs DECIMAL in MySQL 💸
ogImage: /blogs-img/blog8.png
tags: ["mysql", "float", "decimal"]
published: true
---

### 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

```sql
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.

- `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:

```sql
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`.

```sql
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:

```sql
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. ✅
