can't i mod a double ?
and i get:Code:#include<stdio.h> int main() { double a=100; printf("%d",a%16); return 0; }
Code:root@cactus:~/PL# gcc -o mod mod.c mod.c: In function ‘main’: mod.c:6: error: invalid operands to binary %
can't i mod a double ?
and i get:Code:#include<stdio.h> int main() { double a=100; printf("%d",a%16); return 0; }
Code:root@cactus:~/PL# gcc -o mod mod.c mod.c: In function ‘main’: mod.c:6: error: invalid operands to binary %
Evidently not. modulus only makes sense for integer divisions. You could cast it to an int first.
Isn't a double a floating point? I'm a C total n00b so I might be wrong but as far as I am aware...Originally Posted by spank
1) When you assign a value to a float, you have to add a decimal point to the assigned value.
2) The signifier for a double is %lf. You have put in %d which I believe is for int
3) I think I read somewhere that double is not always available and it depends on the system you are using.
Could it be that one of these things is causing the problem? Maybe someone with more experience can say for sure. In my short time here, people have been incredibly helpful and knowledgable, I'm sure someone will be able to point out the problem.
Hope this helps,
TV
Code:SYNOPSIS #include <math.h> double fmod(double x, double y); float fmodf(float x, float y); long double fmodl(long double x, long double y); DESCRIPTION The fmod() function computes the remainder of dividing x by y. The return value is x - n * y, where n is the quotient of x / y, rounded towards zero to an integer.
Not really, you need a decimal point for an expression like float f = 1/2.0; because otherwise 1/2 is integer and evaluates to 0 instead of the desired 0.5. Something like float f = 2; is fine. However, it would be good practice when initialising a floating point type to add the .0 for clarity.Originally Posted by tvsinesperanto
Actually with printf, doubles use %f. %lf is only valid for scanf. This is because floats and doubles both become doubles when passed to printf.2) The signifier for a double is %lf. You have put in %d which I believe is for int
Any conforming C compiler will have the double type.3) I think I read somewhere that double is not always available and it depends on the system you are using.
Ah, OK. My text book says that you "should always put in the decimal point". I took that to mean that it was required but I see now that it could be read as a suggestion. Thanks for putting me straight on that.Originally Posted by cwr
Ok, so does that mean that, when using a double in a printf() function, you must use %f and can't use %lf or that it makes no difference whether you use %lf or %f?Originally Posted by cwr
Referring, once again, to my text book, it seems to imply that you should use %lf. It actually says...
"These [referring to a table below that contains a list of signifiers and their corresponding types in which %lf is matched to double] are used in all *f() functions: printf(), scanf(), fprintf(), sscanf(), sprintf(), and so forth."*
* Pg 368 "C Programming" by Larry Ullman and Marc Liyanage
So, is the text incorrect then? I am starting to have concerns about my text book if this is the case.
This was actually my mistake this time, I simply misread the book. It actually says that a long double is not always available. Sorry about that.Originally Posted by cwr
Sorry to hijack the thread like this but I am concerned that my text book may be steering me wrong in places. Should I start a new thread perhaps?
The former: you must use %f. %lf is invalid for printf(). (But you must use %lf for scanf(); %f in scanf() reads a float instead of a double.)Ok, so does that mean that, when using a double in a printf() function, you must use %f and can't use %lf or that it makes no difference whether you use %lf or %f?
Your book is a bit misleading. Which one is it?
[edit]
Never mind, I see you posted its title.
[/edit]
dwk
Seek and ye shall find. quaere et invenies.
"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell
Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net
My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, nort, etc.
long double should be around on newer compilers, like Dev-C++. It's part of the C99 standard.It actually says that a long double is not always available.
dwk
Seek and ye shall find. quaere et invenies.
"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell
Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net
My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, nort, etc.
Yeah, I am really impressed with the layout and the way it explains things but I'm now quite concerned that it may contain erorrs.Originally Posted by dwks
Oh well, I guess that is what forums are for...
Thanks for the help.
Cheers,
TV
That actually applies to any function whever passing a float by value. The compiler expands a float to double, push the double on the stack, then in the receiving function that declares it as a float in the parameter list, the compiler has to shrink it back to a float. Programs that may be speed critical should just use doubles everywhere to avoid all those conversions.This is because floats and doubles both become doubles when passed to printf.
I'd be interested in more information on this. Some of my googling has led me to things such as "default argument promotions" and "when a function is called with no prototype in scope" and stuff about K&R1 vs C89. I'll continue digging, but if you have quickie links I would be grateful.Originally Posted by Ancient Dragon
7. It is easier to write an incorrect program than understand a correct one.
40. There are two ways to write error-free programs; only the third one works.*
Are you talking about the specific behaviour of one architecture, or are you saying this happens generally?Originally Posted by Ancient Dragon
Edit: Followup:
I made this simple program below that calls a function taking a float many many times...
I then timed it:Code:#include <stdio.h> float foo(float f) { return f+1.0; } int main(void) { int i; float f = 0; for (i = 0; i < 100000000; i++) f = foo(f); printf("%f", foo); return 0; }
I then replaced the above code to use doubles everywhere instead of float:Code:$ gcc -o float float.c $ for ((i=0; i<5; i++)); do time ./float; done 2>&1 | grep real real 0m1.110s real 0m1.098s real 0m1.097s real 0m1.108s real 0m1.097s
Here we see double is much slower. Let's try with -O2:Code:$ cat float.c | sed 's/float/double/g' > double.c $ gcc -o double double.c $ for ((i=0; i<5; i++)); do time ./double; done 2>&1 | grep real real 0m4.235s real 0m4.325s real 0m4.390s real 0m4.301s real 0m4.270s
The timing is now basically identical. I'm not sure there is any significant overhead for function calls with double versus float?Code:$ gcc -O2 -o float float.c $ for ((i=0; i<5; i++)); do time ./float; done 2>&1 | grep real real 0m0.931s real 0m0.923s real 0m0.933s real 0m0.923s real 0m0.933s $ gcc -O2 -o double double.c $ for ((i=0; i<5; i++)); do time ./double; done 2>&1 | grep real real 0m0.934s real 0m0.922s real 0m0.935s real 0m0.922s real 0m0.933s
Oh, the above timings are on a Pentium 4 3.0Ghz using gcc 3.3 under linux 2.6. I did have a look at the assembly output, but my x86 asm is a little rusty, so I couldn't really comment constructively.
Update:
Here are the same timings with -O2 using gcc 4.0 and a PowerPC (ppc) G4 1.0GHz under MacOS X 10.4:
Here we see double is indeed faster, but this may also be to do with the add operation, not just the function call overhead.Code:$ for ((i=0; i<5; i++)); do time ./float ; done 2>&1 | grep real real 0m4.170s real 0m4.212s real 0m4.071s real 0m4.187s real 0m4.096s $ for ((i=0; i<5; i++)); do time ./double ; done 2>&1 | grep real real 0m2.754s real 0m3.216s real 0m3.023s real 0m2.797s real 0m2.762s
Last edited by cwr; 03-05-2006 at 10:39 PM.