How do I handle round-off errors in my MATLAB code?
66 次查看(过去 30 天)
显示 更早的评论
MathWorks Support Team
2013-3-13
编辑: MathWorks Support Team
2024-11-8
How does MATLAB handle rounding and how do I resolve round-off errors in my MATLAB code?
采纳的回答
MathWorks Support Team
2024-11-8
编辑:MathWorks Support Team
2024-11-8
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 个评论
Jan
2017-12-8
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(:)))
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrices and Arrays 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!