96 views (last 30 days)

Show older comments

I am unable to determine if the error in my answer is the result of round-off error or a bug.

MathWorks Support Team
on 17 Feb 2021

Edited: MathWorks Support Team
on 17 Feb 2021

You have encountered a round-off error that 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 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))

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:

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(:)))

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!