0

If I just change the data type float to double in the following program, the code works fine for input 14.2 (and all inputs). However, if I use float instead of double, the program behaves strangely that, it works fine for all inputs EXCEPT 14.2!

#include <stdio.h>
#include <ctype.h>

void totalPrice(char, float);

int main()
{
   char gasStation;
   float tankSize;

   printf("Enter the gas station: \n");
   scanf("%c", &gasStation);
   gasStation = toupper(gasStation);

   printf("Enter the size of the gas tank: \n");
   scanf("%f", &tankSize);

   totalPrice(gasStation, tankSize);
}

void totalPrice(char gasStation,  float tankSize)
{
   float amount;

   switch(gasStation)
   {
      case 'I': 
      if (tankSize == 5)
      amount = (5*75.49) + (0.09*(5*75.49)) + (0.09*(5*75.49));
      else if (tankSize == 14)
      amount = (14.2*75.49) + (0.09*(14.2*75.49)) + (0.09*(14.2*75.49));
      else if (tankSize == 19)
      amount = (19*95.50) + (0.12*(19*95.50)) + (0.12*(19*95.50));
      break;

      case 'B':
      if (tankSize == 5)
      amount = (5*77.50) + (0.09*(5*77.50)) + (0.09*(5*77.50));
      else if (tankSize == 14.2)
      amount = (14.2*77.50) + (0.09*(14.2*77.50)) + (0.09*(14.2*77.50));
      else if (tankSize == 19)
      amount = (19*97.50) + (0.12*(19*97.50)) + (0.12*(19*97.50));
      break;

      case 'H':
      if (tankSize == 5)
      amount = (5*79.50) + (0.09*(5*79.50)) + (0.09*(5*79.50));
      else if (tankSize == 14.2)
      amount = (14.2*79.50) + (0.09*(14.2*79.50)) + (0.09*(14.2*79.50));
      else if (tankSize == 19)
      amount = (19*99.50) + (0.12*(19*99.50)) + (0.12*(19*99.50));
      break;

      default:
      printf("Unable to read tankSize\n");
   }
   amount+=20; //Delivery charge

   printf("Total price to be paid for refilling the gas (including GST) is INR: %f", amount);
}

Above code doesn't work. However, changing the data type of tankSize, amount, and the second parameter to totalPrice to double from float cause the code to work.

Why do the integer inputs (5 and 19) work in all cases but input 14.2 works only when data type is double?

irowe
  • 638
  • 11
  • 21
  • 1
    Maybe you could explain what it means for this program to "work"? – Scott Hunter Feb 02 '23 at 15:23
  • Comparing floating point numbers with `==` is probably not what you want to do... – General Grievance Feb 02 '23 at 15:25
  • 2
    Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – General Grievance Feb 02 '23 at 15:26
  • 1
    It may be the difference between `14.2` and `14.2F`. There's enough difference between the `float` and `double` representations of 14.2 that your code using `float` will fail because the `float` is promoted to `double` for the comparison. Integers have an exact representation in binary; most decimal fractions do not have an exact binary representation. – Jonathan Leffler Feb 02 '23 at 15:29
  • These aren't iron-clad rules, but as a general guideline: (1) Never use type `float`; always use type `double`. (2) Don't compare floating-point values for exact equality, and especially not when they have fractional parts. Even a "nice, even" value like 0.2 is *not* nice or even in the base-2 encoding used internally. – Steve Summit Feb 02 '23 at 22:16

1 Answers1

2

In this if statement

else if (tankSize == 14.2)

you are comparing a float number stored in the variable tankSize of the type float with a double constant 14.2.

Double values have higher precision than float values.

You should compare two float values

else if (tankSize == 14.2f)

Using the suffix f makes the floating constant of the type float.

From the C Standard (6.4.4.2 Floating constants)

4 An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has type float. If suffixed by the letter l or L, it has type long double.

That is instead of the floating constant 14.2 of the type double you should use the floating constant 14.2f of the type float.

Here is a demonstration program

#include <stdio.h>

int main( void )
{
    float tankSize;

    printf( "Type 14.2: " );
    scanf( "%f", &tankSize );

    if (tankSize == 14.2)
    {
        puts( "tankSize is equal to double 14.2." );
    }
    else
    {
        puts( "tankSize is not equal to double 14.2." );
    }

    if (tankSize == 14.2f )
    {
        puts( "tankSize is equal to float 14.2f." );
    }
    else
    {
        puts( "tankSize is not equal to float 14.2f." );
    }
}

The program output is

Type 14.2: 14.2
tankSize is not equal to double 14.2.
tankSize is equal to float 14.2f.
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335