Storing Money and Float Precision (2024)

Let me iterate the content before we begin. The main goal of this article is to discuss how currency values can be stored in databases (MySQL). My secondary goal is to explain the inaccuracy with float values. Now that we’ve clarified the scope, let’s get started The requirement is straightforward. In our database, we must store currency values or numeric values where precision is critical. The approaches or solutions provided below use MySQL, and the coding is done in Java, but I hope the fundamentals are clear to you. Another quick note: Some relational databases, such as Postgres, support a Money type, but we’ll stick to MySQL to keep things simple. Let’s look at the different data types that can be used to store currency values:

Storing Money and Float Precision (2)

Let’s look at the different data types that can be used to store currency values:

  1. Float / Double
  2. Decimal / Numeric
  3. Bigint / Integer
  4. Varchar / String

Okay, we’ve compiled a list of our top solutions. To be clear, I did not list them by data type. As you can see, Float and Double are two distinct data types (Double stores double-precision floating-point number values), but what they bring to the table under this topic is fairly straightforward. Now comes the exciting part.

If precision is a requirement, this may be a no; why maybe? let me explain. It is advised to avoid using this data type to save currency values. Why are float and double not as precise as you might think?

Let’s take a look at this small code snippet.

class HelloWorld { public static void main(String[] args) { double total = 0.2;
System.out.println(“Initial Value : “ + total);
for (int i = 0; i < 10; i++) {
total += 0.2;
}
System.out.println(“Total Value : “ + total);
}
}

We increment out the initial value ten times with addition, and we get an output like the following:

Initial Value : 0.2Total Value : 2.1999999999999997

We expected 2 but got 2.1999999999999997 . Now we have an issue in our hands; if we chop the value, we get 2.1 or if we rounded it off, we get 2.2 Either way, we have a close to 0.1 loss of precision (or loss of significance)

Okay, why does that happen? Before I point you down to the solution, something you need to know is

Floats were according to IEEE 754 always binary

The term "float" refers to the decimal point 'floats'. For instance, the following are all different exponents with the same whole number:

1. 10.25 is 1025 x 10^(-2)2. 0.15 is 15 x 10^(-2)

But I said floats were binary, right? Yes, computers think in binary. So it's something like

1. 10.25 is 164 x 2^(–4) which is 10.252. 0.15 is 168884986026394 x 2^(–50) which is close to 0.15

Computers use binary numbers because they are faster at dealing with them and because a small error can usually be ignored in most calculations. Another important point to note is that it is not due to binary. For example, can we accurately represent a number like (1/3) in Base 10? You have to round to something like 0.33, and you don’t expect 0.33 + 0.33 + 0.33 to equal 1.

Okay, now for the explanation. I’m just going to copy-paste the answer, which perfectly explains everything.

Extracted from Wikipedia:

Whether or not a rational number has a terminating expansion depends on the base. For example, in base-10 the number 1/2 has a terminating expansion (0.5) while the number 1/3 does not (0.333…). In base-2 only rationals with denominators that are powers of 2 (such as 1/2 or 3/16) are terminating. Any rational with a denominator that has a prime factor other than 2 will have an infinite binary expansion. This means that numbers that appear to be short and exact when written in decimal format may need to be approximated when converted to binary floating-point. For example, the decimal number 0.1 is not representable in binary floating-point of any finite precision; the exact binary representation would have a “1100” sequence continuing endlessly:

e = −4; s = 1100110011001100110011001100110011…,

where, as previously, s is the significand and e is the exponent.

When rounded to 24 bits this becomes

e = −4; s = 110011001100110011001101,

which is actually 0.100000001490116119384765625 in decimal.

Float uses 24-bit for its "mantissa", which holds all the significant digits. This means it has about seven digits of precision (as 2^(24) is about 16 million), and Double uses 53-bit for its "mantissa", so it can hold about 16 digits accurately.

To summarise, the result of a floating-point calculation is frequently rounded in order to fit back into its finite representation. This rounding error is a defining characteristic of floating-point computation. Assume you want to perform a certain level of complex multiplication, This will have an impact on your calculation flow and final values if not addressed (this is not limited to multiplication; other arithmetic operations will have the same effect, although on a smaller scale for obvious reasons).

This is one of the better ways to save currency values without incurring any losses. It’s not difficult to understand.

decimal(15,2)

15 is the precision (total length of value including decimal places), and 2 is the number of digits after the decimal point; of course, length and precision can be defined to meet your needs. Assume your application must handle money values up to a trillion dollars. In that case, the following should work: 13,2 and If you must adhere to GAAP (Generally Accepted Accounting Principles), use 4 for precision, such as 13,4.

Another method is to store it as an integer. The only takeaway is that you must perform a calculation. Why? Because there are no decimal places, you must store the values by multiplying by 100 or 1000, depending on the level of precision desired. Integer (INT) has a signed range of -2147483648 to 2147483647 and an unsigned range of 0 to 4294967295. In the column definition, you can specify whether the int is signed or unsigned. The signed range for Bigint is -9223372036854775808 to 9223372036854775807, and the unsigned range is positive. Unsigned has a value range of 0 to 18446744073709551615. More information is available in the MySQL Documentation. This is sufficient for general-purpose business applications to store currency values, but it imposes an additional burden when dealing with fractional values. Not recommended, but it depends on your needs and feasibility, which applies to all of the solutions I’ve listed here.

I’m just going to add this to the list for the sake of completeness: You can use VARCHAR to store exact representations, but one important takeaway aside from the obvious is that it takes more bytes to store a number as a string. And any arithmetic on the value will always convert it to a number.

Okay, we talked about the float precision issue. We talked about the various currency data types. The goal has been met. Have a great day all.

  1. IEEE 754 — Wikipedia, https://en.wikipedia.org/wiki/IEEE_754
  2. Floating-point arithmetic — Wikipedia, https://en.wikipedia.org/wiki/Floating-point_arithmetic#Representable_numbers.2C_conversion_and_rounding
  3. DECIMAL Data Type Characteristics — MySQL, https://dev.mysql.com/doc/refman/8.0/en/precision-math-decimal-characteristics.html
Storing Money and Float Precision (2024)
Top Articles
Best Savings Accounts in Germany in 2024 – Expat Guide
A|T FINANCES: RETIREMENT ACCOUNTS 101
Craigslist Vans
What are Dietary Reference Intakes?
Chalupp's Pizza Taos Menu
5 Bijwerkingen van zwemmen in een zwembad met te veel chloor - Bereik uw gezondheidsdoelen met praktische hulpmiddelen voor eten en fitness, deskundige bronnen en een betrokken gemeenschap.
Corpse Bride Soap2Day
ds. J.C. van Trigt - Lukas 23:42-43 - Preekaantekeningen
True Statement About A Crown Dependency Crossword
Florida (FL) Powerball - Winning Numbers & Results
Used Wood Cook Stoves For Sale Craigslist
Nonuclub
Zürich Stadion Letzigrund detailed interactive seating plan with seat & row numbers | Sitzplan Saalplan with Sitzplatz & Reihen Nummerierung
Nebraska Furniture Tables
Classic Lotto Payout Calculator
Viha Email Login
Napa Autocare Locator
Grayling Purnell Net Worth
Epguides Strange New Worlds
Skip The Games Fairbanks Alaska
Craigslist Pearl Ms
Is Windbound Multiplayer
Yosemite Sam Hood Ornament
Play It Again Sports Norman Photos
Avatar: The Way Of Water Showtimes Near Maya Pittsburg Cinemas
Elite Dangerous How To Scan Nav Beacon
Craigslist Hunting Land For Lease In Ga
800-695-2780
Wonder Film Wiki
Is Henry Dicarlo Leaving Ktla
Waters Funeral Home Vandalia Obituaries
How do you get noble pursuit?
30+ useful Dutch apps for new expats in the Netherlands
Srjc.book Store
Ringcentral Background
Noaa Marine Forecast Florida By Zone
Moonrise Time Tonight Near Me
new haven free stuff - craigslist
Jr Miss Naturist Pageant
Craigslist Lakeside Az
Buhsd Studentvue
Sunrise Garden Beach Resort - Select Hurghada günstig buchen | billareisen.at
Skip The Games Grand Rapids Mi
RECAP: Resilient Football rallies to claim rollercoaster 24-21 victory over Clarion - Shippensburg University Athletics
Makes A Successful Catch Maybe Crossword Clue
CrossFit 101
Noga Funeral Home Obituaries
Goosetown Communications Guilford Ct
Kenmore Coldspot Model 106 Light Bulb Replacement
Noelleleyva Leaks
Vrca File Converter
Latest Posts
Article information

Author: Frankie Dare

Last Updated:

Views: 5682

Rating: 4.2 / 5 (53 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Frankie Dare

Birthday: 2000-01-27

Address: Suite 313 45115 Caridad Freeway, Port Barabaraville, MS 66713

Phone: +3769542039359

Job: Sales Manager

Hobby: Baton twirling, Stand-up comedy, Leather crafting, Rugby, tabletop games, Jigsaw puzzles, Air sports

Introduction: My name is Frankie Dare, I am a funny, beautiful, proud, fair, pleasant, cheerful, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.