Issue when input to sin(x) is in scientific notation
3 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Anna Joy
am 17 Apr. 2023
Kommentiert: Anna Joy
am 17 Apr. 2023
I have an issue where the output of sin(x) is incorrect when x is given in scientific notation. If I manually reformat x to be in non-scientific notation (i.e. 1.34*10^2 => 134), the output of sin(x) is the same as that from a calculator (I used Desmos to verify). All variables are in double
Why is this happening, and what can I do about it? Is there a command to reformat x, or an I missing something else?
dT = 0.1;
T = 0:dT:5;
A= 5;
f= 60
w= 2*pi*f
l = w*T(28)
% using scientific notation -----------------------
V_direct = 5*sin((w*T(28))) % doesn't match expected
V_var = 5*sin((l)) % doesn't match expected
V_sci = 5*sin((1.0179e+3)) % matches expected
V_hardcode = 5*sin(1017.9) % matches expected
% w/o using scientific notation -----------------------
V_direct = A*sin((30*2)) % using direct multiplication
l = 30*2
V_direct = A*sin(30*2) % matches expected
V_var = A*sin(l) % matches expected
V_hardcode = A*sin(60) % matches expected
0 Kommentare
Akzeptierte Antwort
Star Strider
am 17 Apr. 2023
You are seeing the effects of different precision arguments.
format long % Show Details In Variables
dT = 0.1;
T = 0:dT:5;
A= 5;
f= 60
w= 2*pi*f
l = w*T(28)
% using scientific notation -----------------------
V_direct = 5*sin((w*T(28))) % doesn't match expected
V_var = 5*sin((l)) % doesn't match expected
arg_1 = (1.0179e+3) % Hard-Coded, Limited Precision Argument
dif = arg_1 - l % Difference Betqeen Hard-Coded & Actual Value
V_sci = 5*sin((1.0179e+3)) % matches expected
V_sci_2 = 5*sin(arg_1 - dif) % Subtract Difference From Hard-Coded Value & Evaluate
V_hardcode = 5*sin(1017.9) % matches expected
% w/o using scientific notation -----------------------
V_direct = A*sin((30*2)) % using direct multiplication
l = 30*2
V_direct = A*sin(30*2) % matches expected
V_var = A*sin(l) % matches expected
V_hardcode = A*sin(60) % matches expected
So precision counts! The sin function is giving the correct results, however the differences between the ‘expected’ results with limited precision arguments and the results of the full-precision arguments account for the differences in the results that you see.
.
2 Kommentare
Weitere Antworten (2)
Walter Roberson
am 17 Apr. 2023
Bearbeitet: Walter Roberson
am 17 Apr. 2023
dT = 0.1;
T = 0:dT:5;
You are assuming that T will be in terms of nice even fractions, same as if you had specified T = [0, 1/10, 2/10, 3/10, 4/10, ... 50/10]
However, that is not the case.
fprintf('%.999g\n', 0.1)
So literal 0.1 converts internally to a number that is just slightly larger than 1/10, and the way that the colon operator works is [0, 0+dt, 0+dt+dt, 0+dt+dt+dt ...] and so on, accumulating that "slightly more than 1/10" with each step.
format long g
T = T(:);
T_more_exact = ((0:50)/10).';
T_difference = T - T_more_exact;
mask = T_difference ~= 0;
[T(mask), T_more_exact(mask), T_difference(mask)]
0.1 does not correspond to exactly 1/10 .
This is not a bug in MATLAB. In every finite-length fixed--number-base system, there will always be values that cannot be exactly represented within the representation system. Base 10 cannot, for example, exactly represent 1/3 in any finite length. If 1/3 -> 0.3333333333333 then 0.333333333333333 * 3 = 0.999999999999999 not 1 exactly in base 10. You could try using 1/3 -> 0.333333333333334 but multiply that by 3 and you get something that ends in 2 not something that ends in 0. The same problem happens for base 100, base 1000, base 60, base 1492 -- it is an inherent problem with finite representation of fractions.
Also... you should be using sinpi
Oguz Kaan Hancioglu
am 17 Apr. 2023
Your sampling is not sufficient to analyze 60-hertz sine waves. When you update your sampling which is equal to dt, the sine wave or function is correctly working.
dT = 0.001;
T = 0:dT:5;
A= 5;
f= 60 ;
w= 2*pi*f;
l = w*T(28)
V_old = A * sin(2*pi*f.*(0:0.1:5));
V = A * sin(2*pi*f.*T);
figure;
subplot(2,1,1)
plot(T,V)
hold on;
plot((0:0.1:5),V_old)
subplot(2,1,2)
plot(T,V)
hold on;
plot((0:0.1:5),V_old)
axis([0 0.5 -5 5])
V_direct, V_var and V_sci are the same.
% using scientific notation -----------------------
V_direct = 5*sin(w*T(28)) % doesn't match expected
V_var = 5*sin((l)) % doesn't match expected
V_sci = 5*sin((10.1788)) % matches expected
Siehe auch
Kategorien
Mehr zu Measurements and Spatial Audio finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!