1

Just getting started in C programming and learning about overflow. The following code I created has no issues and complies fine. What I want to know is why? For instance when I replace variables product1 and avg1 with the datatype long long why would it result in an output of nan nan. Why would using type double be better than long long when the size in terms of bytes are similar? Also was it valid for me to cast type double when variables are double already.

#include <stdio.h>

int main(void) {
   int userNum1;
   int userNum2;
   int userNum3;
   int userNum4;
   
   /* Type your code here. */
   scanf("%d %d %d %d", &userNum1, &userNum2, &userNum3, &userNum4);
   
   int product = userNum1 * userNum2 * userNum3 * userNum4;
   double product1 = (double)userNum1 * userNum2 * userNum3 * userNum4;
   int avg = (userNum1 + userNum2 + userNum3 + userNum4) / 4;
   double  avg1 = ((double)userNum1 + userNum2 + userNum3 + userNum4) / 4; 
   printf("%d %d\n", product, avg);
   printf("%0.3lf %0.3lf\n", product1, avg1);  

   return 0;
}

desired output when input is 8 10 5 4

1600 6 //output of ints
1600.000 6.750 //floating points
6
  • 1
    You can't use %lf with long long. If you do, it attempts to treat them as floating point values, which obviously won't work. Your compiler should have warned about incompatible formats (make sure your warning level is high enough). Commented Jan 22, 2021 at 19:17
  • Yeah so assume the datatype and the type identifier were also changed to satisfy the complier. Commented Jan 22, 2021 at 19:20
  • Please show the code that doesn't work instead of the code that does work. Commented Jan 22, 2021 at 19:23
  • "Was it valid for me to cast type double when variables are double already?" The casted variables are not double already, they are int. Casting to double ensures that floating point arithmetic is used, otherwise it would be integer arithmetic. Commented Jan 22, 2021 at 19:26
  • @WeatherVane went ahead and edited the code I am referring to the floating point variables. Commented Jan 22, 2021 at 19:33

2 Answers 2

1

What I want to know is why?

Code compiled but not with a well enabled compiler.

Save time, enable all warnings - it is more productive than posting on SO.

long long  product1 = userNum1 * userNum2 * userNum3 * userNum4;
...
printf("%0.3lf %0.3lf\n", product1, avg1);

warning: format '%lf' expects argument of type 'double', but argument 2 has type 'long long int' [-Wformat=]

Use matching print specifiers like "%g" with double and "%lld" with long long.


Also was it valid for me to cast type double when variables are double already.

Yes, but unnecessary.

Sign up to request clarification or add additional context in comments.

5 Comments

THANKS MATE. but what do you mean by unnecessary?
@DEZMO27 With an object like double xx, coding (double) xx serves little purpose (except to insure wider math is not used). Notice that (double)userNum1 is not casting a double object/variable, but an int object.
@DEZMO27 In general, avoid casting. It may narrow the computation. Code could have been double avg1 = (userNum1 + userNum2 + userNum3 + userNum4) / 4.0; or double avg1 = (0.0 + userNum1 + userNum2 + userNum3 + userNum4) / 4; or double avg1 = Num1; avgs = (avg1 + userNum2 + userNum3 + userNum4) / 4; - depending on coding goals. If pressed for performance, perhaps long long sum = 0LL + userNum1 + userNum2 + userNum3 + userNum4; double avg1 = sum / 4.0;
Gotcha so instead of casting I could have made the numbers such as 1, 4 or even at times adding an 0.0 to floats would do the trick. I understand what happened there now. So in short casting should only be used when absolutely necessary unless proven otherwise. Thanks again for the your help.
@DEZMO27 Yes. Casting has it places, like printing a type without a known matching print specifier: printf("%Lg\n", (long double) time(0)); as time_t might be int, long long, double, ...
1

What I want to know is why?

You would get the least number of error messages by default because of not setting advanced flags. You should consider adding -pedantic and -Wall flags to increase the warning level.

... why would it result in an output of nan nan?

It's not necessary everyone will get output like that, in my case, it was 0.000 0.000 (gcc-9.3.0-ubuntu). Let's come to the point, it's because the type specifier becomes invalid as soon as you change the datatype from double to long long. You need %lli to print long long.

Why would using type double be better than long long when the size in terms of bytes is similar?

The reason is that unsigned long long will store exact integers whereas double stores a mantissa (with limited 52-bit precision) and an exponent. Its capability's dependent upon the system arch.

Also was it valid for me to cast type double when variables are double already?

Yes, it's valid. If you don't explicitly make one of the double, then integer arithmetic will take place.

2 Comments

Thankyou I appreciate the help. It was the format specifiers.
@DEZMO27 it was more than that. There was much confusion for you, now cleared most probably.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.