Thread: C and Cpp GCC Compiler Issues

  1. #1
    Registered User Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    9

    Question C and Cpp GCC Compiler Issues

    First I actually thought there was something wrong with my programming skills. But after I compiled the same code using Visual Studio, it worked. So here's the code that doesn't seem to be working right with gcc compilers, but they do compile. Note I'm using the Cygwin 3.4.4 version of gcc and 4.5.1 version of gcc from MinGW.

    Code:
    #include <stdio.h>
    #include <math.h>
    int main()
    {
        long double r = 0;
        long double p = 0;
    
        printf ("Enter a number: ");
        scanf ("%lf", &r);
        printf ("Enter its power: ");
        scanf ("%lf", &p);
        printf ("%lf to the power of %lf = %lf\n", r, p, pow(r, p));
    
        printf ("7 ^ 3 = %lf\n", pow (7.0,3.0));
        printf ("4.73 ^ 12 = %lf\n", pow (4.73,12.0));
        printf ("32.01 ^ 1.54 = %lf\n", pow (32.01,1.54));
        return 0;
    }
    This is the first one. It compiles with GCC but the output doesn't seem to be what I'm expecting. (MinGW gcc (GCC) 4.5.1)
    Code:
    Enter a number: 5
    Enter its power: 3
    5.000000 to the power of 0.000000 = 0.000000
    7 ^ 3 = 343.000000
    4.73 ^ 12 = 125410439.217423
    32.01 ^ 1.54 = 208.036691
    The part "5.000000 to the power of 0.000000 = 0.000000" doesn't seem to be right. But on the other hand, when I compiled it using Visual Studio, it worked very well.
    Code:
    Enter a number: 5
    Enter its power: 3
    5.000000 to the power of 3.000000 = 125.000000
    7 ^ 3 = 343.000000
    4.73 ^ 12 = 125410439.217423
    32.01 ^ 1.54 = 208.036691
    I looked for a solution in the internet and I found sscanf. I tried to modified the code, it still compiles with gcc but yielding the same results.
    Code:
    #include <stdio.h>
    #include <math.h>
    int main()
    {
        char line[100];
        long double r = 0;
        long double p = 0;
       
        printf ("Enter a number: ");
        fgets(line,sizeof(line),stdin);
        sscanf(line,"%lf",&r);
        
        printf ("Enter its power: ");
        fgets(line,sizeof(line),stdin);
        sscanf(line,"%lf",&p);
        
        printf ("%lf to the power of %lf = %lf\n", r, p, pow(r, p));
    
        printf ("7 ^ 3 = %lf\n", pow (7.0,3.0));
        printf ("4.73 ^ 12 = %lf\n", pow (4.73,12.0));
        printf ("32.01 ^ 1.54 = %lf\n", pow (32.01,1.54));
        return 0;
    }
    Using the gcc compiler of MinGW this is the result: (MinGW gcc (GCC) 4.5.1)
    Code:
    Enter a number: 5
    Enter its power: 3
    5.000000 to the power of 0.000000 = 0.000000
    7 ^ 3 = 343.000000
    4.73 ^ 12 = 125410439.217423
    32.01 ^ 1.54 = 208.036691
    The previous yields the same result as before where the part "5.000000 to the power of 0.000000 = 0.000000" is not working as intended. If I use the compiler from Visual Studio 2008 C++, this is the result:
    Code:
    Enter a number: 5
    Enter its power: 3
    5.000000 to the power of 3.000000 = 125.000000
    7 ^ 3 = 343.000000
    4.73 ^ 12 = 125410439.217423
    32.01 ^ 1.54 = 208.036691

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The format specifier "%lf" is for double, not long double. Use "%Lf" instead.

    Similarly, the function for raising long double's to a power is powl() not pow().

    If your code worked with Visual Studio, you just got lucky. The mismatching of format specifiers formally gives undefined behaviours (which means anything is allowed to happen).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    9

    Question I made some modifications, but it's still the same.

    Quote Originally Posted by grumpy View Post
    The format specifier "%lf" is for double, not long double. Use "%Lf" instead.

    Similarly, the function for raising long double's to a power is powl() not pow().

    If your code worked with Visual Studio, you just got lucky. The mismatching of format specifiers formally gives undefined behaviours (which means anything is allowed to happen).
    I edited the code as you suggested but it still yields the same result. But still, thank you very much for seeing my mistake. It should have been %Lf instead of %lf. Anyway, the result is still the same in my MinGW gcc.

    Code:
    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
        char line[100];
        long double r = 0;
        long double p = 0;
        
        printf ("Enter a number: ");
        fgets(line,sizeof(line),stdin);
        sscanf(line,"%Lf",&r);
        
        printf ("Enter its power: ");
        fgets(line,sizeof(line),stdin);
        sscanf(line,"%Lf",&p);
        
        printf ("%Lf to the power of %Lf = %Lf\n", r, p, pow(r, p));
    
        printf ("7 ^ 3 = %Lf\n", pow (7.0,3.0));
        printf ("4.73 ^ 12 = %Lf\n", pow (4.73,12.0));
        printf ("32.01 ^ 1.54 = %Lf\n", pow (32.01,1.54));
        return 0;
    }
    Here's the output:
    Code:
    Enter a number: 5
    Enter its power: 3
    5.000000 to the power of 0.000000 = 0.000000
    7 ^ 3 = 343.000000
    4.73 ^ 12 = 125410439.217423
    32.01 ^ 1.54 = 208.036691
    Regarding the powl() function, i didn't try it seems, as shown in the last three lines of the result, pow is already working great. And I tried to search powl() in Google, I cannot seem to find a documentation about it. Anyway, I believe pow() is already working fine. It's just that my scanf() isn't.

    But if I change them all to double. They seem to work fine though.

    Code:
    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
        double input = 0.0;
    	double power = 1.0;
    
    	printf ("Enter a number: ");
        scanf ("%lf", &input);
        printf ("Enter its power: ");
        scanf ("%lf", &power);
        printf ("%.2lf to the power of %.2lf = %.2lf\n", input, power, pow(input, power));
    
        printf ("7 ^ 3 = %lf\n", pow (7,3));
        printf ("4.73 ^ 12 = %lf\n", pow (4.73,12));
        printf ("32.01 ^ 1.54 = %lf\n", pow (32.01,1.54));
        return 0;
    }
    My MinGW gcc compiler does scan and print the correct values.
    Code:
    Enter a number: 5
    Enter its power: 3
    5.00 to the power of 3.00 = 125.00
    7 ^ 3 = 343.000000
    4.73 ^ 12 = 125410439.217423
    32.01 ^ 1.54 = 208.036691
    But I want to use the long double.
    Last edited by Bangonkali; 12-11-2010 at 03:42 AM. Reason: Added examples.

  4. #4
    Registered User
    Join Date
    Dec 2010
    Posts
    15
    It's just that my scanf() isn't.
    I get warnings from gcc when your code is compiled:
    Code:
    unknown conversion type character 'L' in format
    too many arguments for format
    Seems the compiller does not support long doubles input.

    And success in Visual Studio can be explained: double and long double are the same types there.
    In Win32 programming, however, the long double data type maps to the double, 64-bit precision data type.
    MSDN: Long Double

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Bangonkali View Post
    Regarding the powl() function, i didn't try it seems, as shown in the last three lines of the result, pow is already working great. And I tried to search powl() in Google, I cannot seem to find a documentation about it. Anyway, I believe pow() is already working fine. It's just that my scanf() isn't.
    So you disregard advice given without trying, and then complain when you don't get the results you want ......

    The reason the calls of pow() work later is that you are passing values of type double, not of type long double. 3.0 has type double, not long double.

    Your problem is still that you are passing values of type long double to a function expecting values of type double.

    powl() is described in the C standard, which trumps anything you have or haven't found with google. powl() is the same as pow(), the only difference being that it accepts arguments of type long double, not of type double.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    9
    Thanks for your prompt replies guys! But I think I have found the answer to my problem now. According to someone who replied to my email it was because gcc was keeping a space in the keyboard buffer. And you can tell if the same thing's happening again if the second input is always 0. He said I should try to use the following code separated by a space instead:

    Code:
    scanf( "%lf %lf", &r, &p );
    I edited my original code to work like this:

    Code:
    #include <stdio.h>
    #include <math.h>
    int main()
    {
        // my personal troubles with long double
        // while using gcc under cygwin and mingw
        long double r = 0;
        long double p = 0;
        long double a = 0;
        
        printf ("Enter a number <space> power: ");
        scanf( "%Lf %Lf", &r, &p );
    	
        // r to the power of p
        a = pow(r,p);
    
        printf ("%.2Lf to the power of %.2Lf = %.2Lf\n", r, p, a);
        printf ("7 ^ 3 = %.2Lf\n", (long double)pow(7.0,3.0));
        printf ("4.73 ^ 12 = %.2Lf\n", (long double)pow(4.73,12.0));
        printf ("32.01 ^ 1.54 = %.2Lf\n", (long double)pow(32.01,1.54));
        return 0;
    }
    Now it works perfectly fine with the following output when compiled with gcc both from MinGW and Cygwin.

    Code:
    5.00 to the power of 3.00 = 125.00
    7 ^ 3 = 343.00
    4.73 ^ 12 = 125410439.22
    32.01 ^ 1.54 = 208.04
    I still don't know how accept value from a second scanf though. If anyone of you who knows how to circumvent this issue please help. I need to accept the second input only after the return has been pressed from the first input and not separated by space.

  8. #8
    Registered User Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    9
    Quote Originally Posted by rags_to_riches View Post
    I'm sorry for that but I was hoping for the fastest way as possible to ask for help. Anyway, I kept track of all my posts and I update them all as soon as I receive answers from other posts. Yes I'm just a newbie and I didn't know it would ........ a lot of people. But in the end I do update them all, and I post related answers from other forums replies so that the thread for each forum will not be left out unsolved in the process.

    These are the forums where I posted the same question and I have been updating them all diligently to avoid leaving them unanswered in the end: Bytes, LinuxForums, CBoard Cprogramming, CodeCall, DreamInCode, ProgrammingForums. I think it would also help a lot of people if they get in to the same situation as I have and they'll directly find the answers to the question from a lot of forums. As I said, I watch over all diligently so none of them is left out in the process.
    Last edited by Bangonkali; 12-12-2010 at 01:53 PM. Reason: Added links to all forums.

  9. #9
    Registered User Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    9
    Quote Originally Posted by grumpy View Post
    So you disregard advice given without trying, and then complain when you don't get the results you want ......

    The reason the calls of pow() work later is that you are passing values of type double, not of type long double. 3.0 has type double, not long double.

    Your problem is still that you are passing values of type long double to a function expecting values of type double.

    powl() is described in the C standard, which trumps anything you have or haven't found with google. powl() is the same as pow(), the only difference being that it accepts arguments of type long double, not of type double.
    I'm sorry, but if you read my reply third above from here, I have solved the problem about the scanf. So I tried powl(), with the following code modifications (Which is necessary to read the second double user input):
    Code:
    #include <stdio.h>
    #include <math.h>
    int main()
    {
        // my personal troubles with long double
        // while using gcc under cygwin and mingw
        long double r = 0;
        long double p = 0;
        long double a = 0;
        
        printf ("Enter a number <space> power: ");
        scanf( "%Lf %Lf", &r, &p );
    	
        // r to the powler of p
        a = powl(r,p);
    
        printf ("%.2Lf to the power of %.2Lf = %.2Lf\n", r, p, a);
        printf ("7 ^ 3 = %.2Lf\n", (long double)powl(7.0,3.0));
        printf ("4.73 ^ 12 = %.2Lf\n", (long double)powl(4.73,12.0));
        printf ("32.01 ^ 1.54 = %.2Lf\n", (long double)powl(32.01,1.54));
        return 0;
    }
    And I got an error during compilation. I'm using Cygwin's gcc compiler in this one. (gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125))
    Code:
    gcc math.c -o math.exe
    /tmp/ccx4vfjk.o:math.c:(.text+0xc2): undefined reference to `_powl'
    /tmp/ccx4vfjk.o:math.c:(.text+0x171): undefined reference to `_powl'
    /tmp/ccx4vfjk.o:math.c:(.text+0x1bb): undefined reference to `_powl'
    collect2: ld returned 1 exit status
    It perfectly works on MSVC++ though with the right results. I also tried it on MinGW's gcc compiler. It compiles but I get the wrong result: (MinGW's gcc (GCC) 4.5.1)
    Code:
    Enter a number <space> powler: 3 5
    3.00 to the power of 0.00 = 0.00
    7 ^ 3 = -0.00
    4.73 ^ 12 = -4635102304097081900000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000000000
    0.00
    32.01 ^ 1.54 = -3675385620508890400000000000000000000000000000000000000000000000
    00000000000000.00
    Last edited by Bangonkali; 12-12-2010 at 02:26 PM. Reason: Please refer to my previous reply regarding the solution with sanf.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Bangonkali View Post
    I'm sorry, but if you read my reply third above from here, I have solved the problem about the scanf. So I tried powl(), with the following code modifications (Which is necessary to read the second double user input):
    Not sure which part of "Windows can't print long doubles" you're having troubles understanding, but there it is. I have posted this code before, but it's been a while and I couldn't find it on a search so here it is again:

    How To Print Long Doubles in Windows Using MinGW (gcc):
    Code:
    char *printf_ld(long double arg, char answer[15]) {
    
        /* For my own sake: scientific notation with six digits */
        double mantissa, exponent, lg;
        lg = log10l(fabs(arg));
        exponent = floor(lg);
        mantissa = pow(10, lg-exponent);
        mantissa = copysign(mantissa, arg);
        sprintf(answer, "%.6fe%+04g", mantissa, exponent);
        return answer;
    }
    You have to provide the string to print into, which gets returned if you want to chain it or whatever. Example:
    Code:
    int main(void) {
    
        long double first = 97.45L;
        long double second = 0.85L;
        long double third = -9.65L;
        char answer[15];
        printf("%s\n", printf_ld(first, answer));
        printf("%s\n", printf_ld(second, answer));
        printf("%s\n", printf_ld(third, answer));
        return 0;
    }

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    It's a waste of time helping you if you're on 8 forums at the same time.

    No one here is going to check ALL of them just to make sure what they're about to say hasn't been said already.

    It's much easier just to ignore you.
    Your best way out now is to declare WHICH forum you want to continue with and mark all the others as abandoned.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    9

    This thread is solved

    THIS PROBLEM IS SOLVED! Thank you for everyone who replied. Not only from this forum but also from all the other forums which I sent this problem to.

    First let me summarize the problem. I'm using scanf to accept a long double value from the user. I used %Lf to accept this and used %.2Lf to printf it. The problem is that I can't do more than 2 scanf's because I can only read the first one if I used Cygwin's gcc compiler and MinGW's gcc compiler. The same code works with VSC++ though.

    However, if I use only double, and use %lf to scanf and printf data, the programs works quite well even if I have many scanf's.

    A person from one forum gave me an idea about keyboard caching. Which basically means, after I enter a value from the first %Lf (long double) another character is also received which totally messes up the next scanf. And thus when I run my initial code, I receive a 0 value for the next scanf.

    I found out that by putting getchar() from between the two scanf's I can circumvent the issue. Let me repeat, the problem only works on long double scanf's using %Lf, it doesn't occur on only doubles using %lf. The following is my final code that really works on gcc.

    Code:
    #include <stdio.h>
    #include <math.h>
    int main()
    {
        // my personal troubles with long double
        // while using gcc under cygwin and mingw
        long double r = 0;
        long double p = 0;
        long double a = 0;
        
        //printf ("Enter a number <space> power: ");
        //scanf( "%lf %lf", &r, &p );
        
        printf ("Enter a number: ");
    	scanf( "%Lf", &r);
        
        printf ("Enter a number: ");
    getchar();	
    	scanf( "%Lf", &p );
        
        // r to the powler of p
        a = pow(r,p);
    
        // put (long double) typecast before pow if you're
        // printing pow directly on printf and you're using
        // Cygwin's gcc (GCC) 3.4.4. You may not edit this 
        // code if you're compiling on VSC++ or MinGW's gcc 
        // (GCC) 4.5.1
        printf ("%.2Lf to the power of %.2Lf = %.2Lf\n", r, p, a);
        printf ("7 ^ 3 = %.2Lf\n", pow(7.0,3.0)); 
        printf ("4.73 ^ 12 = %.2Lf\n", pow(4.73,12.0));
        printf ("32.01 ^ 1.54 = %.2Lf\n", pow(32.01,1.54));
        return 0;
    }
    And also, because of the problem I learned something odd. If you are going to compile with Cygwin's gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) make sure to add (long double) type casting before pow(4.73,12.0) if you are going to directly printf it using %Lf. But if you're going to use MinGW's gcc (GCC) 4.5.1, you must not put (long double) type casting before pow(4.73,12.0) if you are going to directly printf it using %Lf. But both ways work with VSC++.

    I'm just a newbie here and without the help of the many people who replied I could not have found the idea about the getchar() to solve this problem. I didn't know there really are a lot of good people around the internet. And seriously, I'm really sorry for those who I have annoyed because i sent the same thread to many forums. Thank you guys. THIS THREAD IS SOLVED.

  13. #13
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Salem View Post
    It's a waste of time helping you if you're on 8 forums at the same time.
    Think about the effort-hours this guy invokes... If the other boards are like this one, I'd say at least 50 people on each spent at least 5 or 10 minutes reading his post and deciding whether to get involved. Of those 50 about 5 on each board would choose to try to help out, spending perhaps 2 hours each at the task.

    So figure 500 minutes before he gets his first response.
    Another 600 minutes responding to him.

    1100 minutes... 18 3/4 hours .... per forum... 8 forums... that's 150 hours of labour this guy invokes over a space left in an input buffer.... because he's too impatient to wait for a proper answer.

  14. #14
    Registered User Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    9
    Quote Originally Posted by CommonTater View Post
    Think about the effort-hours this guy invokes... If the other boards are like this one, I'd say at least 50 people on each spent at least 5 or 10 minutes reading his post and deciding whether to get involved. Of those 50 about 5 on each board would choose to try to help out, spending perhaps 2 hours each at the task.

    So figure 500 minutes before he gets his first response.
    Another 600 minutes responding to him.

    1100 minutes... 18 3/4 hours .... per forum... 8 forums... that's 150 hours of labour this guy invokes over a space left in an input buffer.... because he's too impatient to wait for a proper answer.
    THIS THREAD IS SOLVED Lol! You're right. I'm sorry. I sincerely apologize for my indiscretion. THIS THREAD IS SOLVED
    Last edited by Bangonkali; 12-12-2010 at 05:05 PM.

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Bangonkali View Post
    THIS THREAD IS SOLVED Lol! You're right. I'm sorry. I sincerely apologize for my indiscretion. THIS THREAD IS SOLVED
    Ok, we get that it's solved.

    I'm pretty sure the gang here (including me) would be happy to chip in if you play fair. I'm also pretty sure the same is true on your other forums. Just keep in mind these are places for information exchange, this is not a place to suck down information then bug... off.

    When I first came here I was stumped on a couple of procedures I was working on. The answers, offered up almost immediately (like next day...) not only solved my problem but taught me something new about C in the process. And you know what... trying to answer questions and getting spanked for my mistakes has taught me a whole lot more since...

    Cooperation is always preferable to Domination.

Popular pages Recent additions subscribe to a feed