April 3rd, 2013, 02:13 PM
Could somebody please show me the proper way to compute the first term of this loop?
I just don't understand how i'm supposed to divide by a factorial. The professor says that if I compute the main term as two separate terms and then combine them, the program will be able to manage the results and give me correct results. However I do not know how to compute the terms separately or even at all. Im very confused about factorials.
Any help would be greatly appreciated. Here is the prompt:
Write a function that accepts two arguments, integer n and real number x, computes the following series, and returns the computed result:
1 – 2(x^2)/1! + 3(x^4)/2! – 4(x^6)/3! + … + [(-1)^n](n+1)(x^2n)/n!
Notation: 5!=5*4*3*2*1 means 5 factorial
The general term is:
negative one to the power of n
multiply by (n plus one)
multiply by x to the power of (2n)
divided by n factorial
Then write a C program that request two input from the user:
-- an integer number, n
-- a real number, x;
call the function passing those two input as arguments,
output the result returned by the function.
You may assume that the user will always input n correctly, i.e., an integer 0
or above, and you are NOT required to test that n is a negative number.
April 3rd, 2013, 02:38 PM
What is it about the factorial? Do you not understand the concept? Or are you just having problems coding? What have you written?
April 3rd, 2013, 02:53 PM
coding. I just taught myself the concept but I cant get the computer to compile what I have.
April 3rd, 2013, 03:05 PM
Is x a function? If so, then you should change it to a more meaningful name.
1i is invalid syntax for an identifier name. If you intended to multiply i by -1, then you need to use the multiplication operator (*).
(x(i*2))/i * fact
Do you really intend to divide by i and then multiply that quotient by fact? Or do you actually intend to also divide that numerator by fact as well as by i? If the latter, then you need to use grouping symbols appropriately (ie, use parentheses).
Oh, and BTW, when you want us to explain error messages or warnings to you, then tell us what those fracking messages are! We're not here to play stupid guessing games with you!
April 9th, 2013, 02:07 PM
dwise1_aol, I am sorry. I thought it was obvious that the compiling issue was due to incorrect syntax in the computation of "term", as you noted the parenthesis.
I will be more specific from now on though. I do appreciate your input.
I also apologize because I accidentally didnt copy and past everything I had. I left out some identifiers (x was not a function, but rather a floating variable requested from user). I knew the syntax was wrong for computing the first term but I was hoping somebody could help me to correct it.
This is what I have so far and it compiles fine, It just never ends up computing. It just sits there. Im pretty positive its because my syntax is wrong in the computation of "term".
'xsq' means X squared, and 'fact' means factorial.
I also figured that, because I am incorporating division, I would need to use FLOAT, so I did.
int main ()
printf("Please enter a value for 'n'\n");
scanf("%f", & n);
printf("Please enter a value for 'x'\n");
scanf("%d", & x);
fact = fact*i;
term = ((-1*(term*xsq))/fact);
sum = sum+ (i*term);
April 9th, 2013, 03:02 PM
I doubt that very much. Though it may appear that way to you because your compiler isn't giving you the warnings that it should. What compiler are you using? Here is what MinGW gcc displays when I compile your program with all warnings turned on (-Wall) (I had #included stdlib.h and stdio.h):
Originally Posted by jaimeribg
When you compiled using your compiler, did you get a similar warning? If so, then why did you ignore it? Warnings not only tell you that there's something that's not right, but it also points you to the line that is problematic and it tells you what it thinks is wrong with that line.
Warnings are more important and useful than error messages. Never ignore warnings!
Here is Line 10:
scanf("%f", & n);
That warning is telling me that the format is specified as float, but that the second argument, rather than being a pointer to a float, is a different datatype. If we look at Line 6 --
-- we see that you had declared n to be an int. That being the case, you needed to have used "%d" to convert the input to an int value.
What value did you input for n? What value do you think got assigned to n? Let us assume that we enter 10. Using hexadecimal notation (you'll see why in a moment) and assuming that an int is 32 bits long (ie, this is a 32-bit compiler, which is true in my case), then storing 10 as an int would yield this value: 0x0000000A (ignoring byte order issues). However, storing 10 as a float would yield this: 0x41200000. As you can see, the two values are not even close to being the same.
If you ran your program and entered 10 for n, then what happens next depends on your compiler, on whether it's a 16- or 32-bit compiler. If you are using Turbo C, then it's 16-bit, but if you're using a more recent compiler then it's most likely 32-bit.
If 32-bit, then n would be have stored in it a value of 1,092,616,192, just over one billion (or a thousand million, depending on what number-naming system you use). That would cause that loop to run for what would appear to be forever.
If 16-bit, then, because Intel is little-endian (first byte in memory is the least significant byte), it would only read the lowest 16 bits, which in this case will be zero. That means that the loop will never be executed and the program would just blow straight through to the end.
Another problem if this is with a 16-bit compiler is that the high-order 16 bits would have overwritten the memory that comes after n; this is called clobbering and is the source of really weird problems, especially when you use a wild pointer. Depending on how the compiler orders the local variables in memory, you would have clobbered either i (which you cannot detect, since you initialize it after you've clobbered it), or some control values in the function's stack (which would caused indeterminable problems, which can sometimes cause the program to crash). BTW, deliberately overrunning a local variable (usually an input buffer) and clobbering the memory locations that follow is the basis for buffer overflow hacker exploits.
Which was it?
If you mean that it blew through to the end and returned you to the command-line prompt, then you have a 16-bit compiler.
Originally Posted by jaimeribg
If you mean that it seems to freeze and "take forever", then it's most likely a 32-bit compiler. Though exactly how 16-bit code would behave would depend on what value you input for n.
This "unexpected" behavior is precisely the reason why you should never attempt to run a program with warnings.
Last edited by dwise1_aol; April 9th, 2013 at 03:12 PM.
April 9th, 2013, 04:10 PM
It did not display any warnings or errors. I did end up figuring out that I used %f instead of %d at the beginning and when I fixed that, the program ran fine and computed the correct result. which, when inputing 2 for 'n', and 2 for 'x' the result should be 17, which it is.
However I believe, based on your notes, that It is a 32bit compiler because after running it, before I corrected my error, it would take forever and never give me a result.
The compiler is the freeware DevC++. My professor requires that I use only this compiler.
Thank you so much for your input though! It really helped me to better understand the scenario.
I still dont understand why It would let me compile without giving me an error though. I know that errors should not be ignored and that is why I kept trying to fix it and clear all errors, but even after I got it to compile without errors it still would'nt run correctly.
April 9th, 2013, 05:16 PM
Dev-C++ is not a compiler, but rather an IDE ("integrated development environment"). The compiler that it uses is MinGW gcc, a port to Windows of the GNU C compiler, gcc. That is the compiler that I used in my reply. And, yes, it is a 32-bit compiler, which you can verify by printf'ing the value of sizeof(int) -- or by reading the limits.h header file.
Indeed, it was by installing Dev-C++ that I obtained the MinGW gcc compiler, which I continue to use even though I immediately gave up on Dev-C++ as being far too buggy to bother with. Through the command-line (the only way I use gcc and the preferable way) I can tell it to display all warnings, which is what the -Wall option was about. There should be a build option in Dev-C++ to do the same. I very highly recommend that you look for it and enable the display of warnings. Perhaps that is described in the help file.
. . .
No, there is no index in the help file about warnings and the section on compiler options is yet to be implemented. But after firing it up I found that options setting:
Under the Tools main menu item, select Compiler Options.
In the Compiler Options dialog box, click on the Settings tab.
In the left pane, click on C Compiler (should be the default).
The third item down in the right pane is "Inhibit all warning messages". Set that to No.
That should enable warnings. Return that %f error to your program and recompile to verify. Remember, it's the same compiler as I used, so it should display the same warning. Let me know whether that worked.
General Good Practice: Always turn warnings on and up!
Ie, some compilers have different warning and error levels through which to set the compiler to be either more or less strict. You want the compiler be be its strictest when it comes to warnings, so you need to turn warnings up. Dev-C++ only allows for turning warnings on or off, assuming that even works.
You do not understand the difference between errors and warnings. You get errors for syntax errors, such that the compiler was completely unable to understand what you wrote. You get warnings if your code merely confuses the compiler, in which case the compiler will generate code to do what it assumes you want, which is almost never what you do actually want. There can be a hazy line between errors and warnings, which gives you even less of an excuse to attent to errors while you ignore warnings.
Originally Posted by jaimeribg
There's no "good practices" rule for ignoring errors, because you cannot ignore an error. If you get an error, then the compiler does not generate an executable, so you can never possibly attempt to run a program that has errors. You are forced to correct all errors if you are ever to hope to run that program.
We do need a Good Practice of not ignoring warnings, because even if it issues warnings, the compiler will still generate an executable. The problem is that that executable will most likely not do what you want it to do; as the old adage says: "Computers don't do what you want them to do, but rather only what you tell them to do." You wanted scanf to read in an integer value and store it in an int, but instead you told it to read in a float and store it in an int, so that is exactly what it did. Yes, it warned you about that (or at least would have if you hadn't disabled warnings), but it still went on ahead and did what you told it to do. Perhaps in other languages that would be been treated as an error, but C was written by and for master programmers who knew what they were doing, so the overriding assumption that C makes is that you know what you are doing; another adage is that "C gives you enough rope to shoot yourself in the foot" (a couple decades ago there were a number of jokes floating around about how the other languages allow you to shoot yourself in the foot; I'm sure they're still posted somewhere).
Turn all warnings on. Do not ignore warnings. If Dev-C++ does not allow you to turn warnings on, then at the very least open a console and go to your project's directory and run gcc from the command line with the -Wall option.
Another computer saying
April 10th, 2013, 10:51 AM
Okay, I understand the difference now. I followed the instructions and "inhibit all warning messages" was already set to "no".
I fixed the mismatched memory location issue, and compiled and ran the program, and it seemed to work but its somehow not computing the factorial correctly I believe.
based on the prompt, when:
n=1 and x=2 sum=-7 (which is correct)
n=2 and x=2 sum=17 (also correct)
n=3 and x=2 sum=-4.33 (which is incorrect)
at this point, when n=3, the sum should equal 25.66
I believe the total term, which at this point should be:
-256/(i+1)! which should be -256/6
but instead I think the reason im getting -4.33 is because the term is doing -256/12 which is -21.33
when adding to previous term, sum now equals 17-21.33
which equals -4.33
so somehow the factorial is not computing correctly and I cant figure out where my syntax is incorrect, or maybe my order of instructions. There are no warnings coming up to let me know of anything to revise, im assuming because it is computing SOMETHING correctly, just not what I want.
April 10th, 2013, 12:11 PM
Yeah, it figures that Dev-C++ would have fouled that up. My work-around is to just use MinGW gcc from the command line, though that might not work as well for you. My supervisor just expressed the same opinion that I have: when you can't get the GUI to do the job, go straight to "DOS" and just do it! Of course, we had had years of experience with MS-DOS before GUIs completely took over. Even now, the very first window I open in the morning is CmdPrompt.
Rereading your problem, you were supposed to read in n as integer and x as floating-point. So what you should have done was to declare x and xsq as float and to scanf x in with %f. Somewhat of a moot point, though keeping xsq as float would be a bit more efficient since you would not have to convert it to float each time you use it, hardly an issue nowadays with our hyper-powerful processors.
This line isn't doing it for you:
term = ((-1*(term*xsq))/fact);
In your code, it's supposed to giving you (using FORTRAN notation, **, since ^ means something entirely different in C):
(x**(2*i)) -- where i is what it is before begin incremented.
It's not giving you that.
Work it through by playing computer with pencil and paper. Or possibly in a spreadsheet. Make columns for each variable, though with an extra column for what you are about to add to sum (I called it "plus_sum"). In the first row write the initial values and then each of the following rows will be the values they become each time through the loop.
I don't have time to go through this too deeply, but then that's your job, not mine (I mean that in a constructive, "this is your learning experience" way). I think that you are trying to do too much in that one line and in the process are changing the math. I think that term needs to only calculate this iteration's value of (x**(2*i)), with the incrementing of i following the calculation of term, not preceding it. Then the calculation of sum would be where you bring all the factors into place, with either another variable keeping track of ((-1)**i) or give that job to fact instead of to term.
Good thinking on your part, basing each iteration's values on the values of the previous iteration. In rewriting term, apply basic algebra to see that (x**(2*i)) can be rewritten as ((x**2)**i). But now I see that that was probably what you were thinking of in the first place.
April 10th, 2013, 07:50 PM
If I may make an observation: the original project assignment specifically says for you to write a function that computes the series. While one could argue that technically, main() is itself a function, the context of the statement would lead one to conclude that you are meant to write a separate function, and call it from main() with the appropriate arguments.
I can understand that, as a new programmer, it may seem that it is easier to work the details out in a single function, then separate the code out later. With experience, however, you will find that this is generally not the case; sub-dividing problem spaces into separate functions is a key tool in the programmer's toolkit, and one which you will want to understand and embrace as quickly as possible.
I would recommend starting with the code to call the function and work with the result, then write the function itself. I would further recommend writing a separate function for the factorial operator, as you will be using it in more than one place and it would help avoid repetition (in the code, I mean).
Oh, one last note: C does not have an exponentiation operator, as dwise1_aol mentioned. You will want to use the pow() function to exponentiate. Note that while that link is to a C++ reference, the first version of the function listed there is the same as the C version.
Last edited by Schol-R-LEA; April 10th, 2013 at 08:04 PM.