i have a variable with initial value : 34-640.4-71.2.
It should appear 0,instead the result is negative. Could you please tell me the reason? thanks
This has to do with how variables are stored in Java.
double variables are precise up to a certain number of decimals digits. In your equation, while none of its parts exceed 1 decimal, rounding is done in the binary format causing this very minor inaccuracy at the 16th decimal.
-1.776E-15 is equal to -0.000000000000001776.
Here is an interesting thread that can give you more insights on the topic:
Whats wrong with this simple 'double' calculation?
One thing you can do to overcome your problem is to round off the error using:
roundToDecimal( 34 - 64*0.4 -7*1.2 , 14 )
This would round your number to 14 decimal places thus rounding off the inaccuracy.
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.
These two long numbers are the same except for the last digit.
test = [];
test(1) = 33777100285870080;
test(2) = 33777100285870082;
but the last digit is lost when the numbers are put in the array:
unique(test)
ans = 3.3777e+16
How can I prevent this? The numbers are ID codes and losing the last digit is screwing everything up.
Matlab uses 64-bit floating point representation by default for numbers. Those have a base-10 16-digit precision (more or less) and your numbers seem to exceed that.
Use something like uint64 to store your numbers:
> test = [uint64(33777100285870080); uint64(33777100285870082)];
> disp(test(1));
33777100285870080
> disp(test(2));
33777100285870082
This is really a rounding error, not a display error. To get the correct strings for output purposes, use int2str, because, again, num2str uses a 64-bit floating point representation, and that has rounding errors in this case.
To add more explanation to #rubenvb's solution, your values are greater than flintmax for IEEE 754 double precision floating-point, i.e, greater than 2^53. After this point not all integers can be exactly represented as doubles. See also this related question.
i have code and use double function several time to convert sym to double.to increase precision , I want to use digits function.
I want to know it is enough that I write digits in the top of code or I must write digits in above of every double function.
digits set's the precision until it is changed again. Calling digits() without any input you get the precision to verify it's set correct.
In many cases digis has absoluetly no influence on symbolic variables because an analytical solution is found. This means there are no precision errors unless you convert to double. When convertig, digits should be set to at least 16 because this matches double precision.
I need to generate a random number that is between .0000001 and 1, I have been using rand(1) but this only gives me 4 decimal points, is there any other way to do this generation?
Thanks!
From the Octave docs:
By default, Octave displays 5 significant digits in a human readable form (option ‘short’ paired with ‘loose’ format for matrices).
So it's probably an issue with the way you're printing the value rather than the value itself.
That same page shows the other output formats in addition to short, the one you may want to look in to is long, giving 15 significant digits.
And there is also the output_precision which can be set as per here:
old_val = output_precision (7)
disp (whatever)
old_val = output_precision (old_val)
Set the output_precision to 7 and it should be ok :)
Setting the output precision won't help though because the number can still be less than .0000001 in theory but you will only be displaying the first 7 digits. The simplest way is:
req=0;
while (req<.0000001)
req=rand(1);
end
It is possible that this could get you stuck in a loop but it will produce the right number. To display all the decimals you can also use the following command:
format long
This will show you 15 decimal places. To switch back go:
formay short
I have a question about adding the number 1 to very small numbers. Right now, I am trying to plot a circular arc in the complex plane centered around the real number 1. My code looks like:
arc = 1 + rho .* exp(1i.*theta);
The value rho is a very small number, and theta runs from 0 to pi, so whenever 1 is added to the real part of arc, MATLAB seems to just round it to 1, so when I type in plot(real(arc),imag(arc)), all I see is a spike instead of a semicircle around 1. Does anyone know how to remedy this so that MATLAB will not round 1 + real(arc) to 1, and instead conserve the precision?
Thanks
rho=1e-6; theta=0:pi/100:pi; arc=1+rho*exp(1i.*theta); plot(arc); figure(); plot(arc-1);
Shows, that the problem is in plot, not in loss of precision. After rho<1e-13 there will be expected trouble with precision.
The two other possible misconceptions:
- doubles have finite precision. 16 decimal digits or 1+2^-52 is the limit with doubles.
- format short vs. format long -- matlab shows by default only 6 or 7 digits
It also happens to be that 6-7 digits is the limit of a 32-bit float, which could explain also that perhaps the plot function in Octave 3.4.3 is also implemented with floats.
Left: 1+1e-6*exp, Right: (1+1e-6*exp)-1
There is a builtin solution for exactly this probem:
exp1m()
log1p()
explicitly:
log(arc)=log1p(rho*exp(1i*theta))
to get what you need.
Of course you need to work in log space to represent this precision, but this is the typical way this is done.
In double precision floating point representations, the smallest number strictly greater than 1 that can be represented is 1 + 2^-52.
This is a limitation imposed by the way non-integer numbers are represented on most machines that can be avoided in software, but not easily. See this question about approaches for MATLAB.