2

Currently working on an assignment and a bit stuck. We are to convert a temperature from Celsius to Fahrenheit. The final answer should output a floating point number if the answer is a decimal, or a integer if it's a whole number. I have it set up to give me the floating point number, but when I enter a number, say '98.6', I'll get 37.00000 rather than 37. Been at it for a few hours trying to combat it on my own but I've run out of ideas. Thanks for the assistance!

int main(void)
{
    float ftemp;
    float ctemp;    

        printf ("Enter a temperature in Fahrenheit: ");
    scanf ("%f", &ftemp);
    ctemp = (100.0 / 180.0) * (ftemp - 32);
    printf ("In Celsius, your temperature is %f!\n", ctemp);

    return 0;
}
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173

4 Answers4

2

There really isn't a good way to do this as you have described. What it really sounds like you want is better string formatting. Try using %g instead of %f in your printf (per this post).

e.g.

printf ("In Celsius, your temperature is %g!\n", ctemp);

Now, if you are hell bent on getting it to use an integer, the closest you can come is with:

int main(void)
{
    float ftemp;
    float ctemp;
    int   ctempi;    

    printf ("Enter a temperature in Fahrenheit: ");
    scanf ("%f", &ftemp);
    ctemp = (100.0 / 180.0) * (ftemp - 32);
    ctempi = (int)ctemp;
    if(ctemp == ctempi) {
         printf("In Celsius, your temperature is %d\n", ctempi);
    } else {
         printf ("In Celsius, your temperature is %f!\n", ctemp);
    }

    return 0;

}

Community
  • 1
  • 1
Joshua Rahm
  • 534
  • 2
  • 5
1

You are printing your number as a float, to print it as an integer:

printf ("In Celsius, your temperature is %d!\n", (int) ctemp);

It uses the d conversion specifier for decimal print and the argument is casted to int as %d requires an int.

ouah
  • 142,963
  • 15
  • 272
  • 331
0

One thing that's tricky about floating point numbers is that they're not exact. A number that can be expressed in decimal without repeating digits might have repeating digits in binary.

So you need to check if the result is an integer, however due to the imprecise nature of floating point something like (1.0 / 3.0 * 3) == 1 might evaluate to false. So you need to see if it's within some threshold of an integer.

if (fabs(ctemp - roundf(ctemp)) < 0.0001) {
    // result is close enough to an integer, so print as integer
    printf ("In Celsius, your temperature is %d!\n", (int)ctemp);
} else {
    // result is not an integer, so print as a float
    printf ("In Celsius, your temperature is %f!\n", ctemp);
}
dbush
  • 205,898
  • 23
  • 218
  • 273
  • Thank you so much for the info. For what I need I'll just use Joshua's method, it's close enough to what is expected. But I will keep your info and mind and bookmark it for future use, cause I'm sure I'll need it. Thank you! – Kyle Steward Sep 26 '15 at 00:41
0

Read input as a string and test for integer-ness.

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>

struct dual {
  char type;
  union {
    int i;
    float f;
  } u;
} dual_T;

dual_T GetNumber(void) {
  dual_T number;
  float f;
  char buf[100];
  if (fgets(buf, sizeof buf, stdin) == NULL) {
    number.type = 'n';
    return number;
  }

  // test for float - sample code possibility
  int n = 0;
  sscanf(buf, "%f %n", &f, &n);
  bool f_possible = n > 0 && *n == 0;

  // test for int - sample code possibility
  n = 0;
  sscanf(buf, "%i %n", &number.u.i, &n);
  bool i_possible = n > 0 && *n == 0;

  if (f_possible) {
    if (i_possible) {
      // If fits as an `int`, go with `int` as likely higher precision.
      if (f >= INT_MIN && f <= INT_MAX) {
        number.type = 'i';
        return number;
      }
    }
    number.type = 'f';
    number.u.f = f;
  } else {
    if (i_possible) {
      number.type = 'i';
    } else {
      number.type = 'n'; // none
    }
  }
  return number;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256