The following short program is taken from a book in numerical analysis (by Mircea Andrecut). It's about bisection (very simple):


double f(double x) { return x*x-3; }

double bisection(double f(double), double a, double b)
    double epsilon = 1E-7, x;
    int kmax, k;

    if (f(a)*f(b) > 0) { printf("\n ERROR f(a)*f(b) > 0 !"); exit(1); }
    kmax = (int)(1+log((b-a)/epsilon)/log(2));
    for (k = 0; k < kmax; k++) { x=0.5*(a+b); if(f(x)*f(a)>0) a = x; else b = x; } 
    return x;

int main(int argc, char* argv[])
    double a, b, x;
    printf("\n Enter the limits of the interval [a,b]\n");
    printf(" a = "); scanf("%1f", &a);
    printf(" b = "); scanf("%1f", &b);
    x = bisection(f, a, b);
    printf(" RESULTS:");
    printf("\n The computed root of f(x) = 0 : x = %1f", x); 
    printf("\n The computed value of function: f(x) = %1f", f(x));

The program gives the correct result (x = 1.732051), but (and strange) independent of the values of a and b, for example if I type a=0 and b=0 I still get the value x = 1.73... and not the error message in the bisection function: ERROR f(a)f(b) > 0. (Clearly f(0)f(0) > 0). But if I go to the main() function and direcly write x = bisection(f,0,0) instead of x = bisection(f,a,b) I get the correct error message. Is there something wrong with the scanf() function? (compiled as: gcc -o bisection bisection.c)

You mistyped the code from the book. The format string for double in scanf() is "%lf", with a lower case L, not 1. For printf() it's just "%f". Adding 1 to either of them introduces a field width, which you probably don't want.

commented: Thank you very much, it works +0

sir, if i want to print double then i have to use "%f" and when i need to input a double, then "%lf" ? is it what u said ? but i always use %f and it works fine for both cases. please clearify.

is it what u said ?


but i always use %f and it works fine for both cases. please clearify.

Working as intended is one effect of undefined behavior. The problem is that by using %f with scanf() and passing in the address of a double, you're lying to scanf(). %f says that you intend to pass the address of a float, and there's no guarantee that the two types are interchangeable inside scanf().

ohh god! what i was doing.. then why "%f" in printf ? why not "%lf" ?

then why "%f" in printf ? why not "%lf" ?

Because a float value will be automagically converted to double in a variable length argument list. There's no need for both %f and %lf because there's no difference after that conversion. However, C99 added redundant support for %lf to printf() because so many people were confused that scanf() and printf() didn't have identical rules.

And before you ask, no, a pointer to float is not converted to a pointer to double in a variable length argument list. So I'm not contradicting myself.

commented: ;) well explained +2

actually, i am confused now. for scanf() it is okay now. can you a little bit explain more about printf ? if i use "%lf" in printf will it work ?

if i use "%lf" in printf will it work ?

Only if you're compiling as C99 or later, otherwise %lf is an unsupported format specifier and you invoke undefined behavior.

hmm.. ok.. and one more thimnng here only. that when i use %Lf for long double variables in my scanf() or printf() then it print -0.0 for any value in the variable.. althoughi can use it the whole code, there is no problem, but when i print it , it print that. why is it so ?

Please post an example program.


int main()
    long double p=778.567;


    return 0;

it's output is : -115403.... something... why is it so ?

Looks fine to me, and works fine on Visual Studio 2012. What compiler and OS are you using?

OS : windows 7 ultimate 32 bit OS
Compiler:- gcc compiler

@ahmedhamdy thankyou..