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

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

 Accepted Answer

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.
.

More Answers (2)

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

1 Comment

Thanks for the note about sinpi, I will use that instead.

Sign in to comment.

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 Comment

Thanks for the note, I forgot I'd been messing with the time step before I pasted the snippet here.

Sign in to comment.

Products

Release

R2022b

Asked:

on 17 Apr 2023

Commented:

on 17 Apr 2023

Community Treasure Hunt

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

Start Hunting!