Today I stumbled onto this plain problem in Matlab:
>> 1/(10^309)
ans =
0
and everything is fine. Now I type:
>> 0.0001/(10^308)
ans =
9.999999999984653e-313
and get very confused. Wasn't the smallest number possible in Matlab realmin=2.225073858507201e-308? Why is the above output not giving 0?
realmin returns the smallest positive normalized floating-point number in IEEE double precision.
There are smaller positive denormal floating point numbers. Have a look at “What Every Computer Scientist Should Know About Floating-Point Arithmetic”.
You might be more interested in eps that returns the smallest increment between distinct numbers.
In help realmin, it says: "REALMIN Smallest positive normalized floating point number."
A normalized floating point number has no leading zeros in the significand - so something like 1.123 * 10^-10. If the significand has leading zeros, like 0.0001 * 10^-10, then it is denormal.
I think eps(0) gives the smallest denormal number available in Matlab.
Related
When I compute the following in Matlab
myeps = abs(3*(4/3-1)-1);
format long e
eps_myeps = [eps ; myeps]
The output is as follows:
eps_myeps =
2.220446049250313e-16
2.220446049250313e-16
Why is myeps not 0? Why does this not hold when the base is 3 instead of 2?
Code 4/3 is 4/3 in math. 4/3 is not exactly encodable as a floating point number. Most floating point numbers are dyadic rationals (an integer times some power of 2) and a nearby value is used.*1 Much like we can not write 4/3 exactly in decimal, only 1.3333333 and stop after so many digits.
In this case, The subtraction is expected to be exact as well as the multiplication and final subtraction. Yet the first quotient is not 4/3 and so the final result might not be 0.0.
*1
decimal 1.3333333333333332593184650249895639717578887939453125
hex 0x1.5555555555555
I feel the OP is also searching for an answer for "How could obtain a 0 as an answer", besides
"Why is myeps not 0". So here is the answer. You'll need the Symbolic Math Toolbox for MATLAB.
You can create symbolic numbers by using sym. Symbolic numbers are
exact representations, unlike floating-point numbers.
So if you type 3*(sym(4)/sym(3)-1)-1 into MATLAB (once you got the toolbox), the answer will be exact
0
Just mind the sym(4)/sym(3) part. If you try sym(4/3), MATLAB will get a floating-point first, then try to convert it to symbolic. That will lose precision and not produce 0 as an answer.
Why does Matlab display 1.0000 when entering 1-10^(-16) but 1 when entering 1-10^(-17)? Is there any difference in floating point treatment or is anything else? Thanks in advance
Basically, MATLAB can only store 16 significant digits.
MATLAB uses IEEE 754 double-precision floating point numbers, which can represent ~16 decimal digits. In this format, 1-10^-16 is stored as:
0x3fefffffffffffff
The next double after this is:
0x3ff0000000000000
which just so happens to be 1. In other words, it's not possible for MATLAB to represent 1-10^17 exactly, so it rounds it to the nearest number it can represent, which turns out to be 1.
realmin "returns the smallest positive normalized floating point number in IEEE double precision". eps(X) "is the positive distance from ABS(X) to the
next larger in mangitude floating point number of the same precision as X".
If I am interpreting the above documentation correctly, then realmin -- the smallest positive number that can be represented -- must be smaller than eps
(0). But:
>> realmin; % 2.2251e-308
>> eps(0); % 4.9407e-324
Obviously, eps(0), which is even smaller, can be represented too. Could someone explain this to me?
This is a floating point issue. You should go read up on denormal numbers.
Briefly, realmin returns the smallest positive normalized floating point number. But it's possible to have denormal numbers that are smaller than this and still representable in floating point, which is what eps(0) returns.
Quick explanation of denormal numbers
A binary floating point number looks like this:
1.abcdef * 2^M
where abcdefg are each either 0 or 1, and M is a number in the range -1022 <= M <= 1023. These are called normalized floating point numbers. The smallest possible normalized floating point number is 1 * 2^(-1022).
The denormal numbers looks like this
0.abcdef * 2^(-1022)
so they can take values that are smaller than the smallest possible normalized floating point number. The denormal numbers linearly interpolate between -realmin and realmin.
Perhaps it is a matter of definition, this is what I see in the documentation of eps:
For all X of class double such that abs(X) <= realmin, eps(X) = 2^(-1074)
eps returns the distance from 1.0 to the next largest double-precision number, so I can use it to interpret the numbers value on negative weight position. But for very large number with value on high positive weight position, what can I use to interpret?
I mean that I need to have some reference to count out computation noise on numbers obtained on Matlab.
Have you read "What Every Computer Scientist Should Know About Floating-Point Arithmetic"?
It discusses rounding error (what you're calling "computation noise"), the IEEE 754 standard for representation of floating-point numbers, and implementations of floating-point math on computers.
I believe that reading this paper would answer your question, or at least give you more insight into exactly how floating point math works.
Some clarifications to aid your understanding - too big to fit in the comments of #Richante's post:
Firstly, the difference between realmin and eps:
realmin is the smallest normalised floating point number. You can represent smaller numbers in denormalised form.
eps is the smallest increment between distinct numbers. realmin = eps(realmin) * 2^52.
"Normalised" and "denormalised" floating point numbers are explained in the paper linked above.
Secondly, rounding error is no indicator of how much you can "trust" the nth digit of a number.
Take, for example, this:
>> ((0.1+0.1+0.1)^512)/(0.3^512)
ans =
1.0000
We're dividing 0.3^512 by itself, so the answer should be exactly one, right? We should be able to trust every digit up to eps(1).
The error in this calculation is actually 400 * eps:
>> ((0.1+0.1+0.1)^512)/(0.3^512) - 1
ans =
9.4591e-014
>> ans / eps(1)
ans =
426
The calculation error, i.e. the extent to which the nth digit is untrustworthy, is far greater than eps, the floating-point roundoff error in the representation of the answer. Note that we only did six floating-point operations here! You can easily rack up millions of FLOPs to produce one result.
I'll say it one more time: eps() is not an indicator of the error in your calculation. Do not attempt to display : "My result is 1234.567 +/- eps(1234.567)". That is meaningless and deceptive, because it implies your numbers are more precise than they actually are.
eps, the rounding error in the representation of your answer, is only 1 part per billion trillion or so. Your real enemy is the error that accumulates every time you do a floating point operation, and that is what you need to track for a meaningful estimate of the error.
Easier to digest than the paper Li-aung Yip recommends would be the Wikipedia article on machine epsilon. Then read What Every Computer Scientist ...
Your question isn't very well worded, but I think you want something that gives the distance from a number to the next smallest double-precision number? If this is the case, then you can just use:
x = 100;
x + eps(x) %Next largest double-precision number
x - eps(-x) %Next smallest double-precision number
Double-precision numbers have a single sign bit, so counting up from a negative number is the same as counting down from a positive.
Edit:
According to help eps, "For all X, EPS(X) is equal to EPS(ABS(X))." which really confuses me; I can't see how that can be consistent with double having a single sign bit, and values not being equally spaced.
I think There is something wrong in Matlab relative to the number of decimal places used to display the number e.
If put
>> sprintf('%.30f',exp(1))
ans =
2.718281828459045500000000000000
enter code here
I think this is wrong because The number and contains an infinite number of decimal places instead of just the 16 that matlab show in this example.
Does anyone know how I can get better accuracy using Matlab?
Thank you.
No, there is not a bug.
By default, numbers in Matlab are represented by double-precision floating point. These have 52 bits of mantissa, which is approximately equivalent to 16 significant figures. Asking Matlab to print out more decimal places will not magically create more precision.
It's very unlikely you will need more precision than this.
Matlab uses IEEE double precision, so that's as good as you will get for vanilla Matlab.
http://www.mathworks.com/support/solutions/en/data/1-1AGHW/?solution=1-1AGHW suggests getting the Symbolic Math Toolbox, which supports variable precision arithmetic. Or use another tool such as Maple.
Some additional information on double precision and MATLAB.
In the full IEEE system, this spacing is
2- 52. MATLAB calls this quantity eps, which is short for
machine epsilon.
eps = 2^(–52)
Before the IEEE standard, different machines had different
values of eps.
The approximate decimal value of eps is 2.2204 • 10-16.
Either eps/ 2or eps can be called the roundoff level. The
maximum relative error incurred when the result of a single
arithmetic operation is rounded to the nearest floating-point
number is eps/ 2. The maximum relative spacing between
numbers is eps. In either case, you can say that the roundoff
level is about 16 decimal digits.