Find the answer to your Linux question:
Results 1 to 6 of 6
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 ...
  1. #1
    Just Joined! Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    4

    Question C and Cpp 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
    Just Joined!
    Join Date
    Nov 2009
    Location
    Sweden
    Posts
    31
    In Visual Studio, the long double type is identical to double, ie 64 bit, but with gcc long double is 80 bit.
    If you want the same result with both compilers, just use double.

  3. #3
    Just Joined! Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    4

    Smile

    Quote Originally Posted by kohog View Post
    In Visual Studio, the long double type is identical to double, ie 64 bit, but with gcc long double is 80 bit.
    If you want the same result with both compilers, just use double.
    I think your explanation is right. And also, this guy replied to me from another forum. There was a mistake on my part too.
    Quote Originally Posted by grumpy
    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).
    Now I know that it's safer to use double because the Visual Studio and gcc compilers have different implementation of types. Thank you very much. I think this issue is solved.

  4. #4
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
    Posts
    1,117
    Hi.

    I don't do much coding in c, so I usually rely on tools like the lint family to help me. For example, placing your first code into file t1.c, and running
    Code:
    splint t1.c
    yields:
    Code:
    Splint 3.1.2 --- 23 Aug 2008
    
    t1.c: (in function main)
    t1.c:9:19: Format argument 1 to scanf (%lf) expects double * gets long double
                  *: &r
      To ignore type qualifiers in type comparisons use +ignorequals.
       t1.c:9:15: Corresponding format code
    t1.c:9:5: Return value (type int) ignored: scanf("%lf", &r)
      Result returned by function call is not used. If this is intended, can cast
      result to (void) to eliminate message. (Use -retvalint to inhibit warning)
    t1.c:11:19: Format argument 1 to scanf (%lf) expects double * gets long double
                   *: &p
       t1.c:11:15: Corresponding format code
    t1.c:11:5: Return value (type int) ignored: scanf("%lf", &p)
    t1.c:12:58: Function pow expects arg 1 to be double gets long double: r
    t1.c:12:61: Function pow expects arg 2 to be double gets long double: p
    
    Finished checking --- 6 code warnings
    which suggests the general area in which to look.

    See man page for details -- I don't know if cygwin / mingw provides a lint-like utility, but it may be worth looking for ... cheers, drl
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

  5. #5
    Just Joined! Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    4
    Thank you very much. I think I'll really try Splint. I looked for it and found only the Windows version for the moment. Thanks.

    But in the end, it seems that the MinGW gcc compiler really does not like long double after all. I have decided to use double for this project. In addition, Visual Studio does not support long double in reality as I have found out. It accepts long double datatyped variables but internally, it considers it only as a double.

  6. #6
    Just Joined! Bangonkali's Avatar
    Join Date
    Dec 2010
    Posts
    4

    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.
    Last edited by Bangonkali; 12-12-2010 at 08:37 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...