2

I have written a program in C and when I compare the same values of a float and a string that is converted into float using function atof results in NOT EQUAL .

    #include<stdio.h>

    main(){

            char str[10] = "54.23" ;
            float val = 54.23 ;


            if( atof(str) == val )
                 printf("\nconverted correctly");
            else
                 printf("\nThen What is the use of atof\n ");


       }

This Program is showing output : "Then What is the use of atof" Please tell me why this anonymous behavior is shown by this program ?

Ajay Yadav
  • 1,625
  • 4
  • 19
  • 29

4 Answers4

5

Never test floats/doubles for equality with ==

Here's a version of your code which actually displays the values in question:

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

int main()
{
    char str[10] = "54.23";
    float val = 54.23;

    printf("atof(str) = %.15f\n", atof(str));
    printf("      val = %.15f\n", val);

    return 0;
}

When you run it you see this:

$ gcc -Wall atof.c
$ ./a.out 
atof(str) = 54.229999999999997
      val = 54.229999542236328
$

The values are close, within the expected accuracy of a single precision float, but they are not identical. Also, as others have noted, atof returns a double, so you are comparing the value of a float promoted to a double with a full precision double as returned by atof.

As always with this type of question, read this before proceding any further with floating point arithmetic in your code. The "take home message" is that you should never compare floats or doubles with == - always compare the absolute difference with an appropriate tolerance value.

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 2
    “Always compare the absolute difference with a tolerance value” is poor advice because it solves the problem of false negatives by creating a problem of false positives. There is not a simple single solution here; users of floating-point should understand it and be thoughtful about the operations they use. – Eric Postpischil Aug 05 '12 at 10:37
2

Because val is an int; when you assign it 54.23 it'll be truncated to 54. And 54 != 54.23.

Even if it was a float, you couldn't expect them to be equal. Here's why.

  • It is also not working while i am trying after changing int to float . You can give it a try. – Ajay Yadav Aug 05 '12 at 07:17
  • @AjayYadav yes, it's also not working, and it's expected. Really, click the link I made in my answer. –  Aug 05 '12 at 07:32
1
double atof(char *str);\\it return double not a float

This comparison is between a float and a double.As you compare between two different types you may get some unexpected output.because every data type having different memory representation as well as different access mechanism.

float represent in memory in different form as compare to double .

you can learn more about this in wikipedia also

http://en.wikipedia.org/wiki/Floating_point#Internal_representation

Again you should include the header file

#include <stdlib.h> \\prototype of atof() present in this header.

if you not provide the proper prototype before use of the function then

return type of function by default int .So I think the return result is definitely different as you expected.

rajesh6115
  • 705
  • 9
  • 21
0

You almost never want to check equality with floating point numbers, because teensy differences will be read as unequal. There are other problems, too. For example, even if you use double precision, for instance, the decimal number "0.1" is represented as "0.10000000000000001".

In this case, your "val" variable is a double precision literal, which is cast to a float. The result probably won't be accurate perfectly. Secondly, your string literal needs to convert from base ten to a base 2 double. So, to compare the atof value to your literal, atof converts a base ten string to a base two double, while "val" was converted from a base ten literal to a base two double to a base two float, and then upcast back to a base two double to do the comparison.

Point of fact, I'm not going to pin down exactly where that lost precision went. Do as Paul's code might suggest and compare the values to within a tolerance.

geometrian
  • 14,775
  • 10
  • 56
  • 132
  • 2
    There is no need to throw up one’s hands and give up understanding where errors occur. These things are reasonably well specified and understood. First, “54.23” in the source text is converted to a double. Any good compiler will convert it to the value representable as a double that is closed to the number 54.23, although the C standard allows a little slack. Then, when `val` is initialized, that double is converted to a float. With any implementation using IEEE 754, the result is the value representable in float that is nearest the double. Converting val from float to double has no error. – Eric Postpischil Aug 05 '12 at 13:06