How do I handle round-off errors in my MATLAB code?
111 views (last 30 days)
Show older comments
MathWorks Support Team
on 13 Mar 2013
Edited: MathWorks Support Team
on 8 Nov 2024 at 7:38
How does MATLAB handle rounding and how do I resolve round-off errors in my MATLAB code?
Accepted Answer
MathWorks Support Team
on 8 Nov 2024 at 0:00
Edited: MathWorks Support Team
on 8 Nov 2024 at 7:38
Round-off errors demonstrates a fundamental problem with the way computers deal with fractional numbers. Some numbers (in fact, "most" of them) cannot be represented exactly in binary form -- specifically, fractional numbers that are not powers of two. This will occur in any computer program using ANSI/IEEE standard math.
MATLAB uses the ANSI/IEEE Standard 754, double precision, for Binary Floating-Point Arithmetic so any non-zero number is written in the following form with "0<=f<1" and integer "e":
+or- (1+f)*2^e
The quantity "f" is the fraction, or less officially, the mantissa. The quantity "e" is the exponent. Both "f" and "e" must have finite expansions in base 2. The finite nature of "f" means that numbers have a limited accuracy and so arithmetic may involve roundoff error. The finite nature of "e" means that numbers have a limited range and so arithmetic may involve under-flow and overflow. As a result, you will sometimes get roundoff errors that will be noticeable, but usually not significant. For example, most of the numbers you are dealing with may be near 1.0e-01, whereas your error is around 1.0e-16.
If you would like to get a closer look at the way the computer sees these numbers, try using the following command:
>> format hex
You will see that numbers like 1/10 have repeating digits. This demonstrates inaccuracy the same way 0.333... represents 1/3. Numbers like 1/8, however, are accurate, as indicated by the zeros in the mantissa.
Most problems caused by roundoff error can be resolved by avoiding direct comparisons between numbers. For example, if you have a test for equality that fails due to roundoff error, you should instead compare the difference of the operands and check against a tolerance. Instead of:
A == B
try this:
abs(A-B) < 1e-12*ones(size(A))
With MATLAB R2024b, a new function, “isapprox”, has been introduced to determine approximate equality. This function encapsulates the logic of defining tolerances, allowing you to specify different levels of absolute and relative tolerances to efficiently address round-off errors. The function can be called as follows:
>> isapprox(A,B)
For more information on this function, you may refer to the documentation below: https://www.mathworks.com/help/matlab/ref/isapprox.html
Furthermore, whenever you run any mathematical software, including MATLAB, the software does various computations. These computations are done by calling low level math libraries like *, +, and ^, not to mention sin, cos, sqrt. The math libraries are supplied with the system's compiler and are therefore system dependent. Thus, you could get different answers on an HP than on a Sun just doing multiplication, but you are unlikely to notice since it will just change one digit, if any. However, after doing a series of computations these differences add up and then you would notice a difference. As stated above, these differences are due to the underlying math libraries, compilers, architecture and how they are implemented.
If you need more precision than MATLAB's standard double-precision arithmetic provides, you can use the Symbolic Math Toolbox to perform calculations symbolically in infinite precision arithmetic. However, the symbolic calculations will be slower than the standard double-precision operations, and not all functions will accept symbolic objects. For more information on the Symbolic Math Toolbox, see:
For more information on troubleshooting these types of problems, see the section "Avoiding Common Problems with Floating-Point Arithmetic" at the following documentation page:
If you're interested in more information on double-precision arithmetic in MATLAB, there's an excellent Cleve's Corner article that discusses these issues. Check out the Fall 1996 MATLAB News and Notes, found at:
1 Comment
Jan
on 8 Dec 2017
abs(A-B) < 1e-12*ones(size(A))
can be simplified to:
abs(A-B) < 1e-12
but this might not be sufficient if A and B are in the magnitude of e.g. 1e-200. Better:
abs(A(:) - B(:)) < 100 * eps(max(abs(A(:)), abs(B(:))))
The limit of 100*eps is chosen magically here. A sufficient value depends on the problem. Maybe only the values of A should be considered, if this contains the "reference values":
abs(A(:) - B(:)) < 100 * eps(abs(A(:)))
More Answers (0)
See Also
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!