Structuring program to always round off any five decimal numbersto zero

1 visualizzazione (ultimi 30 giorni)
In my code, the results displayed are annoying with very lenthy fractional numbers which if actually divided is insignifican. For example
F = - exp(t*x3)*(1262711551877025502231421556075/411376139330301510538742295639337626245683966408394965837152256 + 879015404686425i/365375409332725729550921208179070754913983135744) + exp(p1*t)*cos(q1*t)*(27598641832495742863565849383413328672542006982019799902774379281/105312291668557186697918027683670432318895095400549111254310977536 + 49835990979419693i/5846006549323611672814739330865132078623730171904) + exp(p2*t)*cos(q2*t)*(119736836245515984576451256966513/162259276829213363391578010288128 - 21895279333859301i/1461501637330902918203684832716283019655932542976) - exp(p1*t)*sin(q1*t)*(244148955905429654108869640572109/5846006549323611672814739330865132078623730171904 - 10021248928274823387123781097474250594205428510041i/105312291668557186697918027683670432318895095400549111254310977536) + exp(p2*t)*sin(q2*t)*(76122868185700701518774529615449/1461501637330902918203684832716283019655932542976 - 7298426444619767i/162259276829213363391578010288128)
The above is actually just A(1,1) element of matrix A, you can now imagine 5x5 matrix
AND THIS ACTUALLY EQUALS
F = exp(p1*t)*cos(q1*t)*(0.2621) + exp(p2*t)*cos(q2*t)*(0.7379)
Could the problem have come from the symbolic reprensentation I am using before substitution?
  1 Commento
Matt J
Matt J il 7 Mag 2023
Could the problem have come from the symbolic reprensentation I am using before substitution?
We have no way of knowing what you did to generate F.

Accedi per commentare.

Risposta accettata

Walter Roberson
Walter Roberson il 7 Mag 2023
AND THIS ACUALLY EQUALS
No, it does not actually equal that.
F = str2sym('- exp(t*x3)*(1262711551877025502231421556075/411376139330301510538742295639337626245683966408394965837152256 + 879015404686425i/365375409332725729550921208179070754913983135744) + exp(p1*t)*cos(q1*t)*(27598641832495742863565849383413328672542006982019799902774379281/105312291668557186697918027683670432318895095400549111254310977536 + 49835990979419693i/5846006549323611672814739330865132078623730171904) + exp(p2*t)*cos(q2*t)*(119736836245515984576451256966513/162259276829213363391578010288128 - 21895279333859301i/1461501637330902918203684832716283019655932542976) - exp(p1*t)*sin(q1*t)*(244148955905429654108869640572109/5846006549323611672814739330865132078623730171904 - 10021248928274823387123781097474250594205428510041i/105312291668557186697918027683670432318895095400549111254310977536) + exp(p2*t)*sin(q2*t)*(76122868185700701518774529615449/1461501637330902918203684832716283019655932542976 - 7298426444619767i/162259276829213363391578010288128)')
F = 
F2 = str2sym('exp(p1*t)*cos(q1*t)*(0.2621) + exp(p2*t)*cos(q2*t)*(0.7379)')
F2 = 
F - F2
ans = 
If it actually equalled, the result of the subtraction would be 0.
Does it approximately equal, to 4 decimal places?
vpa(F,4) - vpa(F2,4)
ans = 
vpa(ans,4)
ans = 
No, not approximately equal either.
  2 Commenti
Walter Roberson
Walter Roberson il 7 Mag 2023
Could the problem have come from the symbolic reprensentation I am using before substitution?
The problem is most likely that you attempted to use floating point numbers in symbolic calculations.
Observe
format long g
C = 0.814723
C =
0.814723
syms x
y = x + C
y = 
Why did this not come out as y = x + 0.814723 or y = x + 814723/1000000 ?
The answer is the MATLAB-level 0.814723 is represented in MATLAB as a double precision binary floating point number, which (except for some extremely small numbers) are represented as an integer divided by 2^53, times 2 to some integer power. The (integer divided by 2^53) is arranged such that the integer is between 2^53 exactly and 2^54-1 -- so the ratio (integer divided by 2^53) is arranged to be between 1.0 exactly and the last representable number just smaller than 2.0 exactly. The integer that is chosen is the one that makes the approximating rational number (with power of 2 denominator) as close to the original number as you can get without using more bits.
The fraction 1/10 is not exactly representable in binary floating point, so 814723/1000000 cannot be represented exactly in such a system. This is not a bug in the system: you encounter exactly the same problem with decimal, where you cannot represent exactly 1/3 as a finite decimal number -- 0.333333333333333 is not exactly 1/3 and even if you used 1000 digits, 1000 "3's" in a row the result would not be exactly 1/3 (which you could see by adding three of them together and observing that the result would be 0.9999999....9 not 1.0 exactly.) This is a limit of all finite positional-notation systems.
So why didn't MATLAB "know" to approximate the number it has stored internally as 7338372398420345/9007199254740992 as 814723/1000000 ? Well, the conversion does try for such things, such as 0.81472 being approximated symbolically as 2546/3125 . But beyond about 5 digits, the conversion logic starts guessing, "Maybe they did mean 7338372398420345/9007199254740992 exactly ??" The symbolic conversion system does not have access to the fact that you coded the number as 0.814723 -- it only receives the floating point number that is represented as 7338372398420345/9007199254740992
Basically... don't use floating point numbers with symbolic calculations. Instead, take the time to convert the floating point numbers to the symbolic form that you want -- such as
C = sym('0.814723') %symbolic decimal
C = 
0.814723
C = sym(814723)/sym(10)^6 %symbolic rational
C = 
C = sym(0.814723, 'e') %explicitly use the power-of-2 fraction
C = 
D = sqrt(sym(5))
D = 
E = sym(pi)^2
E = 
I prefer to stay away from symbolic decimals until final calculations -- they have some odd properties about the number of digits stored, the number of digits displayed, and the number of digits used for calculations. And mixing exp() with symbolic decimals risks losing too much precision for the over-all calculation to be valid.
Walter Roberson
Walter Roberson il 7 Mag 2023
By the way, there is
format long g
C = 0.814723
C =
0.814723
syms x
y = x + C;
y
y = 
sympref('FloatingPointOutput', 1)
ans = logical
0
y
y = 
sympref('FloatingPointOutput', 0)
ans = logical
1
but notice that this outputs four decimal places, where you wanted five . The sympref does not offer any way to alter the number of decimal places output. In my experience, this sympref is almost always more trouble than it is worth.

Accedi per commentare.

Più risposte (0)

Prodotti


Release

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by