C language help; Why is my equation not working properly? - Page 1
Forum section: electronics / beginners

author: McPete
author_rank: Regular Contributor
timestamp: July 12, 2016, 01:17:56 pm
content: Hey all,I'm attempting to grind through a set of problems from a programming class, and I'm having a devil of a time getting a pair of equations to behave- It's the calculations for f-3dB points in a series RCL circuit, for which I have been supplied with the equation (which I can't insert for the life of me), and have coded as below.All inputs are used elsewhere in the code and provide sensible answers.The below code, given the following inputs provides these answers;Resistor= 340Inductor=0.22Capacitor=0.0000001F3dbL=1080.253Hz(Fr is 1073.225Hz)F3dbH=1441423.000HzCode:f3dbL=( (1/(2*3.141)) * (0.5 * sqrt( ((resistor/inductor)*(resistor/inductor)) +( 4/(inductor*capacitor)) + (resistor/(2*inductor)) ) ) );f3dbH=( (1/(2*3.141)) * (0.5 * sqrt( ((resistor/inductor)*(resistor/inductor)) +( 4/(inductor*capacitor)) - (resistor/(2*inductor)) ) ) );I would really appreciate if someone could point out my error here- I suspect I have mislaid some parentheses, but I can't quite figure it out. Please excuse me if I've done something blatantly stupid here, I have not written code for several years, and have had to more or less relearn C over the past weeks.Cheers,Pete

author: MosherIV
author_rank: Super Contributor
timestamp: July 12, 2016, 01:28:18 pm
content: HiThe only thing that it looks like it might be doing to down casting floats to integers.Make all variables float (or double).Change the code to :f3dbL=( (1.0/(2.0*3.141)) * (0.5 * sqrt( ((resistor/inductor)*(resistor/inductor)) +( 4.0/(inductor*capacitor)) + (resistor/(2.0*inductor)) ) ) );f3dbH=( (1.0/(2.0*3.141)) * (0.5 * sqrt( ((resistor/inductor)*(resistor/inductor)) +( 4.0/(inductor*capacitor)) - (resistor/(2.0*inductor)) ) ) );

author: Aeternam
author_rank: Unknown
timestamp: July 12, 2016, 01:31:22 pm
content: Worth a try, though it shouldn't matter. As long as one operand is a float the result should be float.Not sure float has enough precision for the cap, try switching everything to double.

author: LazyJack
author_rank: Frequent Contributor
timestamp: July 12, 2016, 01:32:54 pm
content: What are the types of your variables? Trap For Young Players: you can have much fun when C uses the integer division for /.Same for sqrt(). Is it prototyped properly, That is math.h included?

author: kfitch42
author_rank: Frequent Contributor
timestamp: July 12, 2016, 01:36:12 pm
content: I think MosherIV is on the right path, its probably types/casting related.On a (somewhat) related tangent I would recomend using M_PI (which is defined in math.h which your should already be including since you are using sqrt) instead of your poorly rounded pi. Its fewer characters to type, more precise, and more expressive.

author: Jeroen3
author_rank: Super Contributor
timestamp: July 12, 2016, 01:57:13 pm
content: Code:float a = ((resistor/inductor)*(resistor/inductor));float b = ( 4.0f/(inductor*capacitor));float c = (resistor/(2*inductor));float z = (sqrt( a + b + c ) ); // note that sqrt does implicit casts to and from doublefloat c = 0.15915494f;f3dbL = ( c * (0.5f * z) );Reduce the number of statements per line to something humans can still read. You're caught by your own mess right now. It happens to everyone.You have no idea where the function fails because you can only use the disassembly view to step through. You'd need to be a veteran to understand all the float lib calls.Instead, split your function in a few lines. It was already intended to be executed step by step with all the brackets.I think I did the above sample correct.

author: bitshift
author_rank: Regular Contributor
timestamp: July 12, 2016, 02:06:49 pm
content: Quote from: Jeroen3 on July 12, 2016, 01:57:13 pm+1 for this. Just please don't use a,b,c,d etc for the variable names. Give them each a descriptive name so the next guy who has to look at your code doesn't need to spend a lot of time trying to figure out what it is you are trying to do.

author: ynfo
author_rank: Contributor
timestamp: July 12, 2016, 03:56:53 pm
content: Here you go, parentheses were misplaced:Code:doublef3dbL = (1 / (2 * 3.141) * (0.5 * sqrt((resistor / inductor)*(resistor / inductor) + (4 / (inductor*capacitor))) - (resistor / (2 * inductor))));doublef3dbH = (1 / (2 * 3.141) * (0.5 * sqrt((resistor / inductor)*(resistor / inductor) + (4 / (inductor*capacitor))) + (resistor / (2 * inductor))));but heed the advice to build up the equation in smaller parts!

author: JPortici
author_rank: Super Contributor
timestamp: July 12, 2016, 04:49:46 pm
content: besides that it is imperative that you explode your equation in a series of smaller equations, both for your and the compiler's sanity, there are two main sources of error- divisions- sum/subtraction of numbers which has different orders of magnitudethe "division" problem is easy to address. try to reduce everything as a single division.for exampleCode:(resistor / inductor)*(resistor / inductor)will result in less errors if it is computed asCode:(resistor * resistor) / (inductor * inductor)and so onanyway, divide your equation in smaller bits, start the debugger and step between the passages.

author: Kalvin
author_rank: Super Contributor
timestamp: July 12, 2016, 04:55:24 pm
content: Quote from: JPortici on July 12, 2016, 04:49:46 pmHow about using just the plain printf in order to print out the intermediate results. Debugger ...

author: JPortici
author_rank: Super Contributor
timestamp: July 12, 2016, 04:58:19 pm
content: Quote from: Kalvin on July 12, 2016, 04:55:24 pmyeah, that was me back from another full day of embedded programming (like, what the hell is printf?) :roll:

author: Kalvin
author_rank: Super Contributor
timestamp: July 12, 2016, 05:05:23 pm
content: Quote from: JPortici on July 12, 2016, 04:58:19 pmCreating a very simple printf() for an embedded device doesn't take too much of a data / code space if you reduce the formatting options to the minimum. Of course the debugger may have its uses, but in this particular case it looks a bit overkill.

author: JPortici
author_rank: Super Contributor
timestamp: July 12, 2016, 05:08:12 pm
content: Quote from: Kalvin on July 12, 2016, 05:05:23 pmyes, i tend not to do that because various reasons but let's stop here and not derail the topic

author: IanB
author_rank: Super Contributor
timestamp: July 12, 2016, 05:41:01 pm
content: Quote from: McPete on July 12, 2016, 01:17:56 pmI think you might have transcribed the formulas incorrectly.It will be easier to check your work if you use short variable names like R, L, C rather than "resistor", "inductor", "capacitor".Here is what I guess the result ought to be. You should check against your formula:Code:> R=340340> L=0.220.22> C=0.1e-61e-007> f3dbL = ( - R/L + sqrt( (R*R)/(L*L) + 4/(L*C) )) / (4*pi)957.063853731> f3dbH = ( R/L + sqrt( (R*R)/(L*L) + 4/(L*C) )) / (4*pi)1203.03058396

author: IanB
author_rank: Super Contributor
timestamp: July 13, 2016, 03:40:24 am
content: Quote from: McPete on July 12, 2016, 01:17:56 pmI want to try out the MathJax feature, so let me try:\[f_L=\frac{1}{4\pi}\left(-\frac{R}{L}+\sqrt{\frac{R^2}{L^2}+\frac{4}{LC}}\right)\]\[f_H=\frac{1}{4\pi}\left(\frac{R}{L}+\sqrt{\frac{R^2}{L^2}+\frac{4}{LC}}\right)\]Ah, it's pretty cool

author: McPete
author_rank: Regular Contributor
timestamp: July 15, 2016, 11:01:51 am
content: Thankyou for the great replies everyone!Point taken on fragmenting the equations... It is more or less impossible to read as is! Well done, ynfo for actually wading through the morass of those lines!Doing nothing but PCB layout for nearly two years has really taken a toll on my other abilities- I'm a bit hesitant to go back to doing any soldering, lest I get the wrong end of the iron!Cheers,Pete

author: mikerj
author_rank: Super Contributor
timestamp: July 15, 2016, 11:38:59 am
content: Quote from: Kalvin on July 12, 2016, 05:05:23 pmThat entirely depends on the resources available (spare pin, UART etc.), and whether the additional execution time is going to mess anything up.