Home > Software design >  What data types in C language are these variables and where I am wrong?
What data types in C language are these variables and where I am wrong?

Time:06-22

Now I am learning the C language and I have two tasks. Define variables and print them Here is my code:

    #include <stdio.h>

int main()
{
    printf("Excersise 1\n\n");
    int cVarOne = -250;
    int cVarTwo = 250;
    int cVarThree = 4589498;
    double cVarFour = 10000000000000000000;
    double cVarFive = -9000000000000000000;
    
    printf("%d\n%d\n%d\n%.0lf\n%.0lf\n\n", cVarOne,cVarTwo,cVarThree,cVarFour,cVarFive);
    
    printf("Excersise Two\n\n");
    unsigned short cVarSix = 43112;
    int cVarSeven = -1357674;
    int cVarEight = 1357674;
    int cVarNine = -1357674000;
    unsigned int cVarTen = 3657895000;

    printf("%u\n%d\n%d\n%d\n%lu\n", cVarSeven, cVarEight, cVarNine, cVarTen);
    return 0;
}

The problem is that for exercise 1 the following message appears:

Excersise 1

and for exercise two the same numbers that are set as variables are not printed propetly. Here is the result:

Excersise 2

I tried to use different types, but without result. Where am I wrong? What data types and specifiers should be used and why do these errors occur?

I am using this online compiler: https://www.onlinegdb.com/online_c_compiler

Thanks.

CodePudding user response:

The warning in Exercise 2 is self-explanatory, simple use the correct conversion specifier for unsigned int, as taught in chapter 1 of your favourite C book. The rest of this answer is regarding Exercise 1:


Why you get the warning:

Integer constants, these things: 123, have a type just like variables.

10000000000000000000 is not a floating point type since it doesn't end with . (double) or .f (float), but a fixed point signed integer. The compiler will try to find the smallest signed integer type where the value will fit, but it fails to find one at all.

The reason is because 10,000,000,000,000,000,000 = 10^19 is larger than the largest signed 64 bit integer, which can only hold values up to 2^63 - 1 = 9.22*10^18.

The compiler notes however that the value might fit in a 64 bit unsigned integer since 2^64 -1 = 18.44*10^18, large enough. Hence it tries that, but gives you the warning for writing such smelly code.


Solution:

Use 10000000000000000000.0 which is of type double.
Or better yet, use 10e18 which is also double but readable by humans.


General best practices:

  • Never mix floating point and fixed point in the same expression.
  • Never mix float and double in the same expression. (Stay clear of float entirely on most mainstream systems like PC.)
  • When size and portability matters, never use the default integer types of C like int, long etc. Use the types from stdint.h instead.

CodePudding user response:

Each integer type has a fixed size in bytes for internal representations of values. As a result there is a limit for the maximum and a minimum value that can be stored in an integer type.

For example for the type uintmax_t the following characteristics can be provided by the compiler

#include <stdio.h>
#include <inttypes.h>

int main( void )
{
    uintmax_t x = UINTMAX_MAX;

    printf( "sizeof( uintmax_t ) = %zu and the maximum value is %"
            PRIuMAX "\n", sizeof( x ), x );

}

The program output is

sizeof( uintmax_t ) = 8 and the maximum value is 18446744073709551615

When you are using integer constant without suffix like this 10000000000000000000 then the compiler selects the type of the constant the first signed integer type that can represent such a constant. However neither signed integer type including long long int can represent this constant. So the compiler issues a message that such a constant can be represented only in an unsigned integer type.

You could use a constant with a suffix like

double cVarFour = 10000000000000000000llu;

The suffix determines that the constant has the type unsigned long long int.

As for the second message then you have to use correct conversion specifiers with arguments.

The conversion specifier lu is designed to output values of objects of the type unsigned long int. However the corresponding argument of the call of printf

printf("%u\n%d\n%d\n%d\n%lu\n", cVarSeven, cVarEight, cVarNine, cVarTen);

has the type unsigned int

unsigned int cVarTen = 3657895000;

So either use the conversion specifier u like

printf("%u\n%d\n%d\n%d\n%u\n", cVarSeven, cVarEight, cVarNine, cVarTen);

or cast the argument to the type unsigned ling like

printf("%u\n%d\n%d\n%d\n%lu\n", cVarSeven, cVarEight, cVarNine, ( unsigned long )cVarTen);

Also the length modifier l in this format specification %.0lf has no effect. You could just write %.0f

CodePudding user response:

error occurred in exercise 1 because u were trying to store 19 digits in double data type when it can only store upto 15 digits

  • Related