Issue when input to sin(x) is in scientific notation

4 visualizaciones (últimos 30 días)
Anna Joy
Anna Joy el 17 de Abr. de 2023
Comentada: Anna Joy el 17 de Abr. de 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
f = 60
w= 2*pi*f
w = 376.9911
l = w*T(28)
l = 1.0179e+03
% using scientific notation -----------------------
V_direct = 5*sin((w*T(28))) % doesn't match expected
V_direct = -9.7999e-13
V_var = 5*sin((l)) % doesn't match expected
V_var = -9.7999e-13
V_sci = 5*sin((1.0179e+3)) % matches expected
V_sci = 0.1199
V_hardcode = 5*sin(1017.9) % matches expected
V_hardcode = 0.1199
% w/o using scientific notation -----------------------
V_direct = A*sin((30*2)) % using direct multiplication
V_direct = -1.5241
l = 30*2
l = 60
V_direct = A*sin(30*2) % matches expected
V_direct = -1.5241
V_var = A*sin(l) % matches expected
V_var = -1.5241
V_hardcode = A*sin(60) % matches expected
V_hardcode = -1.5241

Respuesta aceptada

Star Strider
Star Strider el 17 de Abr. de 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
f =
60
w= 2*pi*f
w =
3.769911184307751e+02
l = w*T(28)
l =
1.017876019763093e+03
% using scientific notation -----------------------
V_direct = 5*sin((w*T(28))) % doesn't match expected
V_direct =
-9.799897907979814e-13
V_var = 5*sin((l)) % doesn't match expected
V_var =
-9.799897907979814e-13
arg_1 = (1.0179e+3) % Hard-Coded, Limited Precision Argument
arg_1 =
1.017900000000000e+03
dif = arg_1 - l % Difference Betqeen Hard-Coded & Actual Value
dif =
0.023980236907164
V_sci = 5*sin((1.0179e+3)) % matches expected
V_sci =
0.119889693300673
V_sci_2 = 5*sin(arg_1 - dif) % Subtract Difference From Hard-Coded Value & Evaluate
V_sci_2 =
-9.799897907979814e-13
V_hardcode = 5*sin(1017.9) % matches expected
V_hardcode =
0.119889693300673
% w/o using scientific notation -----------------------
V_direct = A*sin((30*2)) % using direct multiplication
V_direct =
-1.524053105511083
l = 30*2
l =
60
V_direct = A*sin(30*2) % matches expected
V_direct =
-1.524053105511083
V_var = A*sin(l) % matches expected
V_var =
-1.524053105511083
V_hardcode = A*sin(60) % matches expected
V_hardcode =
-1.524053105511083
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 comentarios
Anna Joy
Anna Joy el 17 de Abr. de 2023
Makes sense, thank you.
Star Strider
Star Strider el 17 de Abr. de 2023
As always, my pleasure!

Iniciar sesión para comentar.

Más respuestas (2)

Walter Roberson
Walter Roberson el 17 de Abr. de 2023
Editada: Walter Roberson el 17 de Abr. de 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)
0.1000000000000000055511151231257827021181583404541015625
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)]
ans = 13×3
0.3 0.3 5.55111512312578e-17 0.6 0.6 1.11022302462516e-16 0.7 0.7 1.11022302462516e-16 1.2 1.2 2.22044604925031e-16 1.4 1.4 2.22044604925031e-16 1.7 1.7 2.22044604925031e-16 1.9 1.9 2.22044604925031e-16 2.3 2.3 4.44089209850063e-16 2.4 2.4 4.44089209850063e-16 2.6 2.6 -4.44089209850063e-16
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
Oguz Kaan Hancioglu el 17 de Abr. de 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)
l = 10.1788
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_direct = -3.4227
V_var = 5*sin((l)) % doesn't match expected
V_var = -3.4227
V_sci = 5*sin((10.1788)) % matches expected
V_sci = -3.4229
  1 comentario
Anna Joy
Anna Joy el 17 de Abr. de 2023
Thanks for the note, I forgot I'd been messing with the time step before I pasted the snippet here.

Iniciar sesión para comentar.

Categorías

Más información sobre Mathematics en Help Center y File Exchange.

Productos


Versión

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by