
One of the cool things about the decimal module is that it allows us to define the behaviour of Decimal objects in various ways. While relatively complicated, the tuple syntax is best suited to creating Decimal objects programmatically. Removing the outer brackets will cause an error. An exponent of -3 is going to cause the digits to shift 3 spaces to the right, giving us 13.042, while an exponent of 2 is going to give us 1304200.Ī complete example for the number -13.042 looks like this: x = decimal.Decimal((1, (1, 3, 0, 4, 2), -3))Ī really important thing to note here is that we do need the brackets around the outer tuple, as Decimal expects this tuple as a single argument. This tells the Decimal object how many places we need to shift the digits around the decimal point. The third and final item in the tuple is an exponent. For example, the number 1.3042 has the digits (1, 3, 0, 4, 2). The second item in the tuple is another tuple, and this contains all of the digits in the resulting number. A zero in this first position indicates a positive number, while a one represents a negative number. The first element in the tuple is either the number 0 or 1, and this represents the sign of the number (whether it's positive or negative). The tuple we provide to Decimal has three parts. Perhaps the most complicated method of creating a Decimal object is using a tuple, and this method gives us some insight into how Decimal objects work under the hood. There may be cases where you want to preserve this imprecision for some reason, but most of the time, that's not the case. Print(x) # 0.1000000000000000055511151231257827021181583404541015625Ĭonverting straight from a float causes our Decimal object to inherit all of the imprecision that we were trying to avoid in the first place. The example below should make it clear as to why: x = decimal.Decimal(0.1) It's also possible to create a Decimal object from a float, but I'd generally advise against doing this. If you need a precise decimal representation of a number, using strings to create your Decimal objects is a very simple way to achieve this. So what happens when we write 0.1 in Python? Let's take a look: print(f"") # 0.10000000000000000000Īs we can see, printing x to 20 decimal places here gives us 19 zeroes: we don't end up with some random 5s at the end like we did when using float. For example, the number 0.1 has no finite binary representation. ⅓), there are also numbers we can't represent in binary. However, just as there are numbers we can't represent with a finite number of decimal numerals (e.g. Using progressively greater negative powers we can represent all manner of decimal numbers. So, we've done a quick refresher on how integers can be represented in binary, but what about fractions? As it turns out, it works much the same way, just with negative powers.įor example, 2⁻¹ is ½, and 2⁻² is ¼, which means we can now represent 0.75, 0.5, and 0.25. As you can see, binary representations of numbers tend to be a great deal longer than decimal representations, but we can ultimately represent any integer in this way. If we were to add all this up, we'd get 173. In total we have something that looks like this: Every step to the left, the power increases by 1. Another step to the left and we find another 1, this time representing 1 x 2², which is 4. This 0 represents 0 x 2¹, which is 0 x 2. We then take a step to the left, where we find a 0. When numbers are stored in our computers, they are stored in this binary format.Ī binary number might look something like this: 10101101, which happens to be 173.īinary works in powers of 2, so the rightmost 1 in 10101101, represents 1 x 2⁰. Binary, on the other hand, is a base-2 number system and only uses two unique numerals: generally 0 and 1. We use ten unique numerals in various combinations to represent all numbers. The number system that we use in everyday life is a base-10 number system, also known as a decimal number system. A Quick Look at Binaryīefore we can properly understand the problem with floats, we need to do a quick review of how numbers are represented in binary. However, floats aren't our only option, and today we're going to be taking a look at the decimal module, and why you might use it. Floats serve us well for most purposes, such as simple divisions, but they do have limitations that can become incredibly problematic for certain use cases. When working with decimal numbers in Python, we usually turn to floats.
