I wanted to create a vector with three values 1/6, 2/3 and 1/6. Obviously I Matlab has to convert these rational numbers into real numbers but I expected that it would maximize the precision available.
It's storing the values as doubles but it's storing them as -
b =
0.1667 0.6667 0.1667
This is a huge loss of precision. Isn't double supposed to mean 52 bits of accuracy for the fractional part of the number, why are the numbers truncated so severly?
The numbers are only displayed that way. Internally, they use full precision. You can use the format command to change display precision. For example:
format long
will display them as:
0.166666666666667 0.666666666666667 0.166666666666667
So the answer is simple; there is no loss of precision. It's only a display issue.
You can read the documentation on what other formats you can use to display numbers.
you can not store values as 1/2 or 1/4 or 1/6 in to a Double variable... these are stored as decimals behind the system; if you want to store these values , try storing it as string that would work;
Whenever you want to make mathematical calculation using these strings then convert the value into number and continue....
Related
I have an array of integers (they are actually epochs) and I would like to check if they can be represented in double precision floating point without rounding issues.
So I have a large n rows by 1 column array like this:
1104757200
1104757320
1135981260
1135981560
1135982040
1135982280
1135982340
1135982580
1135982880
1135983420
1135984020
1135984140
1135984200
1135985100
1135985340
And I would like to know if they can be stored without losing precision as double precision floating point numbers.
The output could be another array -vector- with 0 or 1 depending on if the number can be represented without losing precision or not.
Any tips on how to do that check in Matlab would be welcomed.
Let's say I create some number A, of the order 10^4:
A = 81472.368639;
disp(A)
8.1472e+04
That wasn't what I wanted. Where are my decimals? There should be six decimals more. Checking the variable editor shows me this:
Again, I lost my decimals. How do I keep these for further calculations?
Scientific notation, or why you didn't lose any decimals
You didn't lose any decimals, this is just MATLAB's way of displaying large numbers. MATLAB rounds the display of numbers, both in the command window and in the variable editor, to one digit before the dot and four after that, using scientific notation. Scientific notation is the Xe+y notation, where X is some number, and y an integer. This means X times 10 to the power of y, which can be visualised as "shift the dot to the right for y places" (or to the left if y is negative).
Force MATLAB to show you all your decimals
Now that we know what MATLAB does, can we force it to show us our number? Of course, there're several options for that, the easiest is setting a longer format. The most used for displaying long numbers are format long and format longG, whose difference is apparent when we use them:
format long
A
A =
8.1472368639e+04
format longG
A
A =
81472.368639
format long displays all decimals (up to 16 total) using scientific notation, format longG tries to display numbers without scientific notation but with most available decimals, again: as many as there are or up to 16 digits, both before and after the dot, in total.
A more fancy solution is using disp(sprintf()) or fprintf if you want an exact number of decimals before the dot, after the dot, or both:
fprintf('A = %5.3f\n',A) % \n is just to force a line break
A = 81472.369
disp(sprintf('A = %5.2f\n',A))
A = 81472.37
Finally, remember the variable editor? How do we get that to show our variable completely? Simple: click on the cell containing the number:
So, in short: we didn't lose any decimals along the way, MATLAB still stores them internally, it just displays less decimals by default.
Other uses of format
format has another nice property in that you can set format compact, which gets rid of all the additional empty lines which MATLAB normally adds in the command window:
format compact
format long
A
A =
8.147236863931789e+04
format longG
A
A =
81472.3686393179
which in my opinion is very handy when you don't want to make your command window very big, but don't want to scroll a lot either.
format shortG and format longG are useful when your array has very different numbers in them:
b = 10.^(-3:3);
A.*b
ans =
1.0e+07 *
0.0000 0.0001 0.0008 0.0081 0.0815 0.8147 8.1472
format longG
A.*b
ans =
Columns 1 through 3
81.472368639 814.72368639 8147.2368639
Columns 4 through 6
81472.368639 814723.68639 8147236.8639
Column 7
81472368.639
format shortG
A.*b
ans =
81.472 814.72 8147.2 81472 8.1472e+05 8.1472e+06 8.1472e+07
i.e. they work like long and short on single numbers, but chooses the most convenient display format for each of the numbers.
There's a few more exotic options, like shortE, shortEng, hex etc, but those you can find well documented in The MathWork's own documentation on format.
I want to receive the string representation of a number, 2 points after the dot.
I'm using MATLAB R2015a, and noticed that num2str function returns inconsistent results:
for 0.511 I get the required result (0.51):
num2str(0.511,2)
ans =
0.51
for 1.711 I get 1.7 instead of 1.71:
num2str(1.511,2)
ans =
1.5
Anyone knows why?
the 'precision' scalar input to num2str is the number of significant digits. if you want to have 2 figures after the decimal point use the 'formatSpec' string argument:
num2str(0.511,'%.2f')
0.51
num2str(1.511,'%.2f')
1.51
From the documentation for num2str():
s = num2str(A,precision) returns a character array that represents the numbers with the maximum number of significant digits specified by precision.
In other words, the second parameter controls the total number of significant figures, not the number of decimal places.
If you want to round to two decimal places, then use the round() function. You can try rounding the number before calling num2str():
num2str(round(1.511,2))
I am reading some data from a CSV file, and I have custom code to parse string values into different data types. For numbers, I use:
val format = NumberFormat.getNumberInstance()
which returns a DecimalFormat, and I call parse function on that to get my numeric value. DecimalFormat has arbitrary precision, so I am not losing any precision there. However, when the data is pushed into a Spark DataFrame, it is stored using DoubleType. At this point, I am expecting to see some precision issues, however I do not. I tried entering values from 0.1, 0.01, 0.001, ..., 1e-11 in my CSV file, and when I look at the values stored in the Spark DataFrame, they are all accurately represented (i.e. not like 0.099999999). I am surprised by this behavior since I do not expect a double value to store arbitrary precision. Can anyone help me understand the magic here?
Cheers!
There are probably two issues here: the number of significant digits that a Double can represent in its mantissa; and the range of its exponent.
Roughly, a Double has about 16 (decimal) digits of precision, and the exponent can cover the range from about 10^-308 to 10^+308. (Obviously, the actual limits are set by the binary representation used by the ieee754 format.)
When you try to store a number like 1e-11, this can be accurately approximated within the 56 bits available in the mantissa. Where you'll get accuracy issues is when you want to subtract two numbers that are so close together that they only differ by a small number of the least significant bits (assuming that their mantissas have been aligned shifted so that their exponents are the same).
For example, if you try (1e20 + 2) - (1e20 + 1), you'd hope to get 1, but actually you'll get zero. This is because a Double does not have enough precision to represent the 20 (decimal) digits needed. However, (1e100 + 2e90) - (1e100 + 1e90) is computed to be almost exactly 1e90, as it should be.
as i know to get zero mean vector from given vector,we should substract mean of given vector from each memeber of this vector.for example let us see following example
r=rand(1,6)
we get
0.8687 0.0844 0.3998 0.2599 0.8001 0.4314
let us create another vector s by following operation
s=r-mean(r(:));
after this we get
0.3947 -0.3896 -0.0743 -0.2142 0.3260 -0.0426
if we calculate mean of s by following formula
mean(s)
we get
ans =
-5.5511e-017
actually as i have checked this number is very small
-5.5511*exp(-017)
ans =
-2.2981e-007
so we should think that our vector has mean zero?so it means that that small deviation from 0 is because of round off error?for exmaple when we are creating white noise or such kind off random uncorrelated sequence of data,actually it is already supposed that even for such small data far from 0,it has zero mean and it is supposed in this case that for example for this case
-5.5511e-017 =0 ?
approximately of course
e-017 means 10 to the power of -17 (10^-17) but still the number is very small and hypothetically it is 0. And if you type
format long;
you will see the real precision used by Matlab
Actually you can refer to the eps command. Although matlab uses double that can encode numbers down to 2.2251e-308 the precission is determined size of the number.
Use it in the format eps(number) - it tell you the how large is the influence of the least significant bit.
on my machine eg. eps(0.3) returns 5.5511e-17 - exactly the number you report.