compare two float values

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • CBFalconer

    #16
    Re: compare two float values

    Eric Sosman wrote:
    CBFalconer wrote:
    >neha_chhatre@ya hoo.co.in wrote:
    >>
    >>actually i want to check wether two float values are equal or
    >>not equal. i.e suppose t and t1 are two float values and i
    >>want to check wether t and t1 are equal or not
    >>
    >#include <float.h /* FLT_EPSILON */
    >#include <math.h /* fabsf() */
    >>
    >int floatequal(floa t t, float t1) {
    >>
    > float criterion;
    >>
    > criterion = (fabsf(t) + fabsf(t1)) * FLT_EPSILON;
    > if (fabsf(t - t1) criterion) return 0; /* not equal */
    > else return 1; /* equal */
    >} /* untested */
    >
    Needs a little more work for NaNs and infinities ...
    >
    More to the point, the choice of a proper epsilon is
    not dictated solely by the machine's precision, but also
    by the computations that produced the numbers. For example,
    if you calculate a binomial coefficient as
    Ignoring NaNs and infinities, the criterion I used is sufficient to
    guarantee that an equal/nonequal decision can be made. At most
    that criterion is too large by a factor of two, giving an excessive
    range of equality. BTW, I believe there is no guarantee that NaNs
    and infinities exist in the floating point system.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home .att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com

    Comment

    • user923005

      #17
      Re: compare two float values

      On Feb 20, 5:00 pm, CBFalconer <cbfalco...@yah oo.comwrote:
      user923005 wrote:
      neha_chha...@ya hoo.co.in wrote:
      >
      can anybody tell me how to compare two float values, say for
      example t and check are two variables declared float how to
      compare t and check
      >
      This should be a FAQ.
      >
      #include <float.h>
      #include <math.h>
      >
      int double_compare (double d1, double d2)
      {
        if (d1 d2)
          if ((d1 - d2) < fabs (d1 * DBL_EPSILON))
            return 0;
          else
            return 1;
        if (d1 < d2)
          if ((d2 - d1) < fabs (d2 * DBL_EPSILON))
            return 0;
          else
            return -1;
        return 0;
      }
      >
      What if d1 == DBL_EPSILON and d2 == -LARGE_NUMBER?  I think you are
      trying to do too much in one routine.  I also think I have the
      foul-up condition fouled. :-)
      Try it.

      Comment

      • user923005

        #18
        Re: compare two float values

        On Feb 20, 5:00 pm, CBFalconer <cbfalco...@yah oo.comwrote:
        user923005 wrote:
        neha_chha...@ya hoo.co.in wrote:
        >
        can anybody tell me how to compare two float values, say for
        example t and check are two variables declared float how to
        compare t and check
        >
        This should be a FAQ.
        >
        #include <float.h>
        #include <math.h>
        >
        int double_compare (double d1, double d2)
        {
          if (d1 d2)
            if ((d1 - d2) < fabs (d1 * DBL_EPSILON))
              return 0;
            else
              return 1;
          if (d1 < d2)
            if ((d2 - d1) < fabs (d2 * DBL_EPSILON))
              return 0;
            else
              return -1;
          return 0;
        }
        >
        What if d1 == DBL_EPSILON and d2 == -LARGE_NUMBER?  I think you are
        trying to do too much in one routine.  I also think I have the
        foul-up condition fouled. :-)
        I would be very interested to see any instance where this compare
        function fails to perform as expected.

        C:\tmp>cl /DUNIT_TEST /W4 /Ox fcomp.c
        Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762
        for 80x86
        Copyright (C) Microsoft Corporation. All rights reserved.

        fcomp.c
        Microsoft (R) Incremental Linker Version 8.00.50727.762
        Copyright (C) Microsoft Corporation. All rights reserved.

        /out:fcomp.exe
        fcomp.obj

        C:\tmp>fcomp
        compare( 1, 1) = 0.
        compare( -1, -1) = 0.
        compare( 1, 1) = -1.
        compare( 1.84467e+019, 1.84467e+019) = -1.
        compare( 2.22045e-016, -1.79769e+308) = 1.

        C:\tmp>type fcomp.c
        #include <float.h>
        #include <math.h>

        int double_compare (double d1, double d2)
        {
        if (d1 d2)
        if ((d1 - d2) < fabs (d1 * DBL_EPSILON))
        return 0;
        else
        return 1;
        if (d1 < d2)
        if ((d2 - d1) < fabs (d2 * DBL_EPSILON))
        return 0;
        else
        return -1;
        return 0;
        }

        int float_compare (float d1, float d2)
        {
        if (d1 d2)
        if ((d1 - d2) < fabsf (d1 * FLT_EPSILON))
        return 0;
        else
        return 1;
        if (d1 < d2)
        if ((d2 - d1) < fabsf (d2 * FLT_EPSILON))
        return 0;
        else
        return -1;
        return 0;
        }

        #ifdef UNIT_TEST

        #include <stdio.h>

        int main ()
        {
        double u = 1.0;
        double v = u + 1e-14;
        double big = 1.0;
        double a = 1.0, b = 0.9999999999999 9999999999999;
        printf ("compare(%* g, %*g) = %d.\n", DBL_DIG+2, a, DBL_DIG+2, b,
        double_compare (a, b));
        a *= -1;
        b *= -1;
        printf ("compare(%* g, %*g) = %d.\n", DBL_DIG+2, a, DBL_DIG+2, b,
        double_compare (a, b));

        big *= 1 << 16;
        big *= 1 << 16;
        big *= 1 << 16;
        big *= 1 << 16;


        printf ("compare(%* g, %*g) = %d.\n", DBL_DIG+2, u, DBL_DIG+2, v,
        double_compare (u, v));


        u *= big;
        v *= big;

        printf ("compare(%* g, %*g) = %d.\n", DBL_DIG+2, u, DBL_DIG+2, v,
        double_compare (u, v));

        u = DBL_EPSILON;
        v = -DBL_MAX;
        printf ("compare(%* g, %*g) = %d.\n", DBL_DIG+2, u, DBL_DIG+2, v,
        double_compare (u, v));

        return 0;
        }

        #endif

        Comment

        • user923005

          #19
          Re: compare two float values

          On Feb 20, 5:59 pm, user923005 <dcor...@connx. comwrote:
          On Feb 20, 5:00 pm, CBFalconer <cbfalco...@yah oo.comwrote:
          [snip]
          What if d1 == DBL_EPSILON and d2 == -LARGE_NUMBER?  I think you are
          trying to do too much in one routine.  I also think I have the
          foul-up condition fouled. :-)
          This version has better formatting, which will allow us to see the
          dirt.
          That makes the output much easier to grok.

          #include <float.h>
          #include <math.h>

          int double_compare (double d1, double d2)
          {
          if (d1 d2)
          if ((d1 - d2) < fabs (d1 * DBL_EPSILON))
          return 0;
          else
          return 1;
          if (d1 < d2)
          if ((d2 - d1) < fabs (d2 * DBL_EPSILON))
          return 0;
          else
          return -1;
          return 0;
          }

          int float_compare (float d1, float d2)
          {
          if (d1 d2)
          if ((d1 - d2) < fabsf (d1 * FLT_EPSILON))
          return 0;
          else
          return 1;
          if (d1 < d2)
          if ((d2 - d1) < fabsf (d2 * FLT_EPSILON))
          return 0;
          else
          return -1;
          return 0;
          }

          #ifdef UNIT_TEST

          #include <stdio.h>

          int main ()
          {
          double u = 1.0;
          double v = u + 1e-14;
          double big = 1.0;
          double a = 1.0, b = 0.9999999999999 9999999999999;
          printf ("compare(%. *g, %.*g) = %d.\n", DBL_DIG+5, a, DBL_DIG+5, b,
          double_compare (a, b));
          a *= -1;
          b *= -1;
          printf ("compare(%. *g, %.*g) = %d.\n", DBL_DIG+5, a, DBL_DIG+5, b,
          double_compare (a, b));

          big *= 1 << 16;
          big *= 1 << 16;
          big *= 1 << 16;
          big *= 1 << 16;


          printf ("compare(%. *g, %.*g) = %d.\n", DBL_DIG+5, u, DBL_DIG+5, v,
          double_compare (u, v));


          u *= big;
          v *= big;

          printf ("compare(%. *g, %.*g) = %d.\n", DBL_DIG+5, u, DBL_DIG+5, v,
          double_compare (u, v));

          u = DBL_EPSILON;
          v = -DBL_MAX;
          printf ("compare(%. *g, %.*g) = %d.\n", DBL_DIG+5, u, DBL_DIG+5, v,
          double_compare (u, v));

          return 0;
          }
          /*
          compare(1, 1) = 0.
          compare(-1, -1) = 0.
          compare(1, 1.0000000000000 1) = -1.
          compare(1844674 4073709552000, 184467440737097 36000) = -1.
          compare(2.22044 60492503131e-016, -1.7976931348623 157e+308) = 1.
          */
          #endif

          Comment

          • Keith Thompson

            #20
            Re: compare two float values

            Mark McIntyre <markmcintyre@s pamcop.netwrite s:
            Kenneth Brody wrote:
            >How would you check for equality if t and t1 were "int"?
            >Now, how would you check for equality if t and t1 were "float"?
            >
            By some different means. Two mathematically identical floats may
            compare inequal by obvious methods.
            Depends on what you mean by "mathematic ally identical".
            >Or did you have something else in mind for what "equal" means?
            >
            Doubtful, but he also probably expected the below to print "true".
            >
            #include <stdio.h>
            #include <math.h>
            int main(void)
            {
            printf("%f %f %s\n",
            exp(log(4.444)) , 4.444,
            exp(log(4.444)) ==4.444?"true": "false");
            return 0;
            }
            >
            $ ./a.out
            4.444000 4.444000 false
            Here you have two floating-point values that result from calculations
            that, if they were carried out with complete mathematical exactness,
            would be equal. But the actual values are not equal, because
            floating-point calculations aren't completely exact. In this case,
            you can see that they're inexact by using a different format. For
            example:

            #include <stdio.h>
            #include <math.h>
            int main(void)
            {
            printf("%.32f\n %.32f\n%s\n",
            exp(log(4.444)) ,
            4.444,
            exp(log(4.444)) ==4.444 ? "true" : "false");
            return 0;
            }

            4.4439999999999 990620835887966 6775
            4.4439999999999 999502620084967 9299
            false

            If you want to know whether two floating-point values are "equal", the
            first thing you have to ask yourself is just what that means. The
            usual recommendation is to test whether the values are close enough --
            but how close is close enough depends on the nature of the
            calculations that generated the values. If the tolerance is too
            tight, numbers that are logically equal might appear to be unequal; if
            it's too loose, numbers that are logically distinct might appear to be
            equal.

            And sometimes exact equality (the built-in "==" operator) is just what
            you want. For example, with a comparison function that checks whether
            two numbers are within some epsilon of each other, you can have X == Y
            and Y == Z, but X != Z. Whether that's a problem depends on the
            algorithm.

            Floating-point arithmetic is very probably harder than you think it is
            unless your name is David Goldberg, and perhaps even if it is.
            Speaking of which, see David Goldberg's paper "What Every Computer
            Scientist Should Know About Floating-Point Arithmetic",
            <http://docs.sun.com/source/806-3568/ncg_goldberg.ht ml>.

            --
            Keith Thompson (The_Other_Keit h) <kst-u@mib.org>
            Nokia
            "We must do something. This is something. Therefore, we must do this."
            -- Antony Jay and Jonathan Lynn, "Yes Minister"

            Comment

            • Richard Bos

              #21
              Re: compare two float values

              user923005 <dcorbit@connx. comwrote:
              On Feb 20, 6:42=A0am, neha_chha...@ya hoo.co.in wrote:
              can anybody tell me how to compare two float values
              say for example
              t and check are two variables declared float how to compare t and check
              >
              This should be a FAQ.
              And surprise, surprise, it is: 14.5, <http://c-faq.com/fp/fpequal.html>.

              Richard

              Comment

              • Joachim Schmitz

                #22
                Re: compare two float values

                user923005 wrote:
                On Feb 20, 5:59 pm, user923005 <dcor...@connx. comwrote:
                >On Feb 20, 5:00 pm, CBFalconer <cbfalco...@yah oo.comwrote:
                [snip]
                >>What if d1 == DBL_EPSILON and d2 == -LARGE_NUMBER? I think you are
                >>trying to do too much in one routine. I also think I have the
                >>foul-up condition fouled. :-)
                >
                This version has better formatting, which will allow us to see the
                dirt.
                That makes the output much easier to grok.
                >
                #include <float.h>
                #include <math.h>
                <snip>
                int float_compare (float d1, float d2)
                {
                if (d1 d2)
                if ((d1 - d2) < fabsf (d1 * FLT_EPSILON))
                <snip>

                Where is fabsf()? Doesn't seem to be avaible on the platform I'm using,
                which claims to be C89.
                What do use instead?

                Bye, Jojo


                Comment

                • CBFalconer

                  #23
                  Re: compare two float values

                  Joachim Schmitz wrote:
                  user923005 wrote:
                  >user923005 <dcor...@connx. comwrote:
                  >>CBFalconer <cbfalco...@yah oo.comwrote:
                  >>>
                  >>[snip]
                  >>>
                  >>>What if d1 == DBL_EPSILON and d2 == -LARGE_NUMBER? I think you
                  >>>are trying to do too much in one routine. I also think I have
                  >>>the foul-up condition fouled. :-)
                  >>
                  >This version has better formatting, which will allow us to see
                  >the dirt. That makes the output much easier to grok.
                  >>
                  >#include <float.h>
                  >#include <math.h>
                  <snip>
                  >int float_compare (float d1, float d2) {
                  > if (d1 d2)
                  > if ((d1 - d2) < fabsf (d1 * FLT_EPSILON))
                  <snip>
                  >
                  Where is fabsf()? Doesn't seem to be avaible on the platform I'm
                  using, which claims to be C89. What do use instead?
                  >From N869, for C99. For C90 use doubles and fabs.
                  7.12.7.2 The fabs functions
                  Synopsis
                  [#1]
                  #include <math.h>
                  double fabs(double x);
                  float fabsf(float x);
                  long double fabsl(long double x);

                  --
                  [mail]: Chuck F (cbfalconer at maineline dot net)
                  [page]: <http://cbfalconer.home .att.net>
                  Try the download section.



                  --
                  Posted via a free Usenet account from http://www.teranews.com

                  Comment

                  • karthikbalaguru

                    #24
                    Re: compare two float values

                    On Feb 20, 9:29 pm, santosh <santosh....@gm ail.comwrote:
                    neha_chha...@ya hoo.co.in wrote:
                    actually i want to check wether two float values are equal or not
                    equal
                    i.e suppose t and t1 are two float values and i want to check wether t
                    and t1 are equal or not
                    >
                    please send in syntax form as in code form
                    >
                    please tell me how to do,
                    >
                    Please quote relevant parts of the post to which you are replying. This
                    is good practise on Usenet.
                    >
                    Comparing floats for equality is fraught with danger as many values are
                    not perfectly representible in binary floating point. You might find
                    that you need to allow for a small variation on either side of the
                    comparison value, just like the margin of error in scientific
                    experiments.
                    >
                    You might want to read:
                    >
                    <http://www.cygnus-software.com/papers/comparingfloats/Comparing%20flo ...>
                    <http://docs.sun.com/source/806-3568/ncg_goldberg.ht ml>
                    I like the links. Nice Collection :):)

                    Karthik Balaguru

                    Comment

                    • user923005

                      #25
                      Re: compare two float values

                      On Feb 20, 11:25 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote:
                      user923005 <dcor...@connx. comwrote:
                      On Feb 20, 6:42=A0am, neha_chha...@ya hoo.co.in wrote:
                      can anybody tell me how to compare two float values
                      say for example
                      t and check are two variables declared float how to compare t and check
                      >
                      This should be a FAQ.
                      >
                      And surprise, surprise, it is: 14.5, <http://c-faq.com/fp/fpequal.html>.
                      Unfortunately, it's hopelessly broken:
                      C:\tmp>reldif
                      RelDif of 1 and -1 is 2

                      C:\tmp>type reldif.c
                      #define Abs(x) ((x) < 0 ? -(x) : (x))
                      #define Max(a, b) ((a) (b) ? (a) : (b))

                      double RelDif(double a, double b)
                      {
                      double c = Abs(a);
                      double d = Abs(b);

                      d = Max(c, d);

                      return d == 0.0 ? 0.0 : Abs(a - b) / d;
                      }

                      int main(void)
                      {
                      printf("RelDif of %.20g and %.20g is %.20g\n", 1.0, -1.0,
                      RelDif(1.0, -1.0));
                      return 0;
                      }

                      Comment

                      • =?UTF-8?q?Harald_van_D=C4=B3k?=

                        #26
                        Re: compare two float values

                        On Thu, 21 Feb 2008 11:53:18 -0800, user923005 wrote:
                        On Feb 20, 11:25 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote:
                        >And surprise, surprise, it is: 14.5,
                        ><http://c-faq.com/fp/fpequal.html>.
                        >
                        Unfortunately, it's hopelessly broken: C:\tmp>reldif
                        RelDif of 1 and -1 is 2
                        What's wrong with that? What answer did you expect, and why?

                        Comment

                        • christian.bau

                          #27
                          Re: compare two float values

                          On Feb 20, 2:47 pm, "Joachim Schmitz" <nospam.j...@sc hmitz-digital.de>
                          wrote:
                          neha_chha...@ya hoo.co.in wrote:
                          can anybody tell me how to compare two float values
                          say for example
                          t and check are two variables declared float how to compare t and
                          check
                          please help me as soon as possible
                          >
                          float t, check;
                          ...
                          if ( t check)
                              printf("%f is greater than %f\n" t, check);
                          else
                              printf("%f is less than %f\n" t, check);
                          >
                          Don't compare for equality, won't work for float (or double), rather compare
                          the difference against some delta that suits your needs for accuracy
                          You are doing nothing but perpetuating stupid myths. In a correct C
                          implementation (and there are a few incorrect ones around), t < check
                          is true if t is less than check, t == check is true if t is equal to
                          check, t check is true if t is greater than check. In an IEEE 754
                          compatible implementation, exactly one of these three will be true
                          unless one of t or check is Not-A-Number, in which case neither
                          condition is true.

                          Once you accept this fact, you then need to accept that floating-point
                          operations are usually not exact, and two calculations that you think
                          should give the same result will often give results that are close
                          together but not necessarily the same. For example, if you write

                          double x = sqrt (2.0) * sqrt (3.0);
                          double y = sqrt (6.0);

                          you can be sure that the results will be close together, but which of
                          x < y, x == y and x y is true is hard to predict. But the point is:
                          If they are equal, then x == y is true, and if they are not equal then
                          x == y is false. The == operator will give you the correct result,
                          except that the correct result may not be what you thought the exact
                          result is.

                          Comment

                          Working...