Are you having trouble getting accurate results when doing calculations in Power Query? Do you add up 0.1 + 0.1 + 0.1 and end up with 0.30000000000000004 instead of 0.3? This is a common problem, and there’s a reason for it.
In this article, we will explain what causes this problem and how you can fix it. The key is understanding how Power Query handles precision in calculations.
Table of contents
1. The Problem
Imagine you start a sequence that starts at 0 and should end at 0.3. And in each step, you increment with 0.1. You would expect Power Query to give you a list of numbers that looks like this: 0, 0.1, 0.2, 0.3. But when you use a Power Query formula, you might be surprised. The list of numbers actually looks like this: 0, 0.1, 0.2.
Let’s generate this series with List.Generate. The result you get is:
= List.Generate(
() => 0, // Start with 0
each _ <= 0.3, // As long as values are <= to 0.3
each _ + 0.1) // add 0.1 in each step
// Returns { 0, 0.1, 0.2 }
You would expect Power Query to return 0.3 as the last value. Why is this happening?
Let’s take a closer look by counting up to 0.4 instead of 0.3. We will also change the numbers into text so we can see the details more clearly.
= List.Generate(
() => 0, // Start with 0
each _ <= 0.4, // As long as values are <= to 0.4
each _ + 0.1, // add 0.1 in each step
each Text.From( _ ) ) // Turn number into text value
// Returns { 0, 0.1, 0.2, 0.30000000000000004, 0.4 }
You get a list of numbers that looks like this: 0, 0.1, 0.2, 0.30000000000000004, 0.4. Can you see the problem? The third number on the list is not exactly 0.3, it is 0.30000000000000004. This is because of the way Power Query handles precision in calculations. Let’s delve into how computers handle precision.
2. How Computers Store Numbers
Computers use a special way to store numbers called binary floating point. This system helps the computer understand and calculate very big and very small numbers quickly. Systems sometimes need to know the distance between galaxies and, other times, the space between atoms. For different use cases, chosen systems have different precision.
Consider this:
- When you work in construction, it does not matter whether an apartment building it is 80m or 80.00001m high.
- A computer chip designer does not care for measurements bigger than 1 meter, but the precision of 0.0001 meters makes a big difference to this designer.
The result of this dynamic range is that the numbers that can be represented are not uniformly spaced. The fact that floating-point numbers cannot precisely represent all real numbers leads to many surprising situations. This is related to the finite precision with which computers generally represent numbers.
3. Why Do We Get Differences?
It’s because computers can’t always store fractions like 1/3 with precision. Instead, they have to use decimal numbers like 0.33 or 0.3334. But, even with these decimal numbers, if you multiply them by 3, they will not always add up to 1.
To avoid these problems, computers use floating-point numbers that have a limited number of digits. These numbers are faster; in our example, the rounding error to the 17th decimal usually does not make a big difference.”
4. Power Query and Numbers
Power Query uses two ways to store numbers: Double-precision and Decimal-precision. Both ways round numbers to the nearest value each system can understand. This means that sometimes, there might be small mistakes before any calculations happen.
4.1. Double-precision
Power Query’s default way to store numbers is called Double-precision. It uses a special way to write fractional values. This system can handle bigger numbers than Decimal-precision. But, it can’t always write decimal numbers like $0.30 precisely.
4.2. Decimal-precision
The other way Power Query stores numbers is called Decimal-precision. This system stores numbers in a different way, which can handle a wider range of values and can write numbers like $0.30 precisely. This is different from Double-precision.
4.3. Why Are Only Some Numbers Wrong?
Sometimes, the precisions of numbers shown in Power Query seem correct, but others appear wrong. How come?
This has to do with the floating-point number and can have two explanations.
- Sometimes, the rounding errors in the input numbers can cancel each other out. This means that one rounding error is positive and the other is negative, so they balance each other.
- Another reason is that the number shown is not exactly 0.2, but it is very close to 0.2. The computer system chooses the closest possible number to 0.2 that it can use and shows that instead of a more exact number.
5. Handling Precision in Power Query
So Power Query uses a system to store numbers that round numbers to the nearest value that it can understand. This can cause small rounding errors, even before any calculations happen.
So, our issue is with the Double-Precision implementation. But there is a way to make sure your numbers are more accurate.
5.1. Precision Type
To return the same calculation with more precision, you can provide a formula with a Precision Type.
The previous formula shown returns the same results as:
= List.Generate(
() => 0,
each _ <= 0.4,
each Value.Add(_, 0.1, Precision.Double ),
each Text.From(_) )
// Returns { 0, 0.1, 0.2, 0.30000000000000004, 4 }
The difference is that this example makes use of the Value.Add function. The benefit of using this function is that it has an optional third argument where you can specify the Precision for your calculation. By default, it makes use of the Precision.Double type, but you can provide it with Precision.Decimal.
= List.Generate(
() => 0,
each _ <= 0.4,
each Value.Add(_, 0.1, Precision.Decimal),
each Text.From(_) )
// Returns { 0, 0.1, 0.2, 0.3, 0.4 }
And the Decimal Precision can store numbers with much more detail. In this case, that results in the correct numbers.
Other Value functions that support the Precision Type parameter are Value.Subtract, Value.Multiply,Value.Divide, Value.Compare, Value.Equals. But you also find the precision Parameter in the list functions List.Sum, List.Product and List.Average.
5.2. Rounding Numbers
Alternatively, instead of using the precision parameter, you can go for a different approach. By using a rounding function like Number.Round, you can return the closest single decimal value.
= List.Generate(
() => 0,
each _ <= 0.4,
each Number.Round( _ + 0.1, 1 ),
each Text.From(_) )
// Returns { 0, 0.1, 0.2, 0.3, 0.4 }
For this example, that worked out, but be careful with rounding. You may end up rounding numbers to a value you’re not looking for. Choose carefully.
6. Conclusion
In conclusion, when working with numbers in Power Query, it’s important to know that the program uses a Double-precision floating point system by default. This can cause small rounding errors even before any calculations happen. But, you can provide the Precision Type Precision.Decimal or use a rounding function, to make sure the numbers are as accurate as you need them to be.
Remember, the precision you choose will depend on the type of numbers you’re working with and what you’re using them for. Now, you can go ahead and make your calculations with confidence!
Happy querying!
Recommended Reading…
Power Query Foundations
Beginners Guide to Power Query
List Functions (200+ Examples)
Text Functions (150+ Examples)
Creating Tables (40+ Examples)
Generate the Ultimate Date Table
Advanced Topics
Master List.Generate with Easy Examples
Deep Dive into List.Accumulate
you can set the data type to Double.Type or use function Double.From to avoid the issues from rounding
I can see why you got to that conclusion. But when you try code like:
The result is: 0.30000000000000004
And when you have a column containing values 0.1, 0.2, 0.3, 0.4 etc, then create a column that adds 0.1 to these values. Transform the type to Double.Type, and then turn it into Text.Type after, again you end up with 0.30000000000000004 for one of the values. You can test it with:
That goes to say that it is still important to be aware of Power Query’s behavior. Even if you don’t see the decimals, they may still be there (but hidden)
Hi there!
that explains alot.
few times this happened and while I work with SAP in accountancy where SAP can give numbers with 13 decimal spaces, when I checked the source file it had normal 2 decimal spaces value. and I was wondering why in PQ it had 13 places,
For me, the decimal error describe is always ….4 at the end. I saw it few times and luckily normal rounding worked for my needs,
However now the mystery is solved why this happens
Mystery solved – I like hearing that. It was a mystery for me too!