# Decimal Numbers In some cases you might need to be able to store decimal numbers with guarantees about the precision. This is particularly important if you are storing things like **currencies**, **prices**, **accounts**, and others, as you would want to know that you wouldn't have rounding errors. As an example, if you open Python and sum `1.1` + `2.2` you would expect to see `3.3`, but you will actually get `3.3000000000000003`: ```Python >>> 1.1 + 2.2 3.3000000000000003 ``` This is because of the way numbers are stored in "ones and zeros" (binary). But Python has a module and some types to have strict decimal values. You can read more about it in the official [Python docs for Decimal](https://docs.python.org/3/library/decimal.html). Because databases store data in the same ways as computers (in binary), they would have the same types of issues. And because of that, they also have a special **decimal** type. In most cases this would probably not be a problem, for example measuring views in a video, or the life bar in a videogame. But as you can imagine, this is particularly important when dealing with **money** and **finances**. ## Decimal Types Pydantic has special support for [`Decimal` types](https://docs.pydantic.dev/latest/api/standard_library_types/#decimaldecimal). When you use `Decimal` you can specify the number of digits and decimal places to support in the `Field()` function. They will be validated by Pydantic (for example when using FastAPI) and the same information will also be used for the database columns. /// info For the database, **SQLModel** will use [SQLAlchemy's `DECIMAL` type](https://docs.sqlalchemy.org/en/20/core/type_basics.html#sqlalchemy.types.DECIMAL). /// ## Decimals in SQLModel Let's say that each hero in the database will have an amount of money. We could make that field a `Decimal` type using the `condecimal()` function: {* ./docs_src/advanced/decimal/tutorial001_py310.py ln[1:11] hl[11] *} Here we are saying that `money` can have at most `5` digits with `max_digits`, **this includes the integers** (to the left of the decimal dot) **and the decimals** (to the right of the decimal dot). We are also saying that the number of decimal places (to the right of the decimal dot) is `3`, so we can have **3 decimal digits** for these numbers in the `money` field. This means that we will have **2 digits for the integer part** and **3 digits for the decimal part**. ✅ So, for example, these are all valid numbers for the `money` field: * `12.345` * `12.3` * `12` * `1.2` * `0.123` * `0` 🚫 But these are all invalid numbers for that `money` field: * `1.2345` * This number has more than 3 decimal places. * `123.234` * This number has more than 5 digits in total (integer and decimal part). * `123` * Even though this number doesn't have any decimals, we still have 3 places saved for them, which means that we can **only use 2 places** for the **integer part**, and this number has 3 integer digits. So, the allowed number of integer digits is `max_digits` - `decimal_places` = 2. /// tip Make sure you adjust the number of digits and decimal places for your own needs, in your own application. 🤓 /// ## Create models with Decimals When creating new models you can actually pass normal (`float`) numbers, Pydantic will automatically convert them to `Decimal` types, and **SQLModel** will store them as `Decimal` types in the database (using SQLAlchemy). {* ./docs_src/advanced/decimal/tutorial001_py310.py ln[24:34] hl[25:27] *} ## Select Decimal data Then, when working with Decimal types, you can confirm that they indeed avoid those rounding errors from floats: {* ./docs_src/advanced/decimal/tutorial001_py310.py ln[37:50] hl[49:50] *} ## Review the results Now if you run this, instead of printing the unexpected number `3.3000000000000003`, it prints `3.300`: