Issue when input to sin(x) is in scientific notation
4 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Star Strider
2023-4-17
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 个)
Walter Roberson
2023-4-17
编辑:Walter Roberson
2023-4-17
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
2023-4-17
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
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!