double or float?

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

    double or float?


    According to the docs, floats are 32 bit and doubles are 64 bit. So
    using floats should be faster than using doubles on a 32 bit processor,
    and my tests confirm this. However, most of the Math methods deal with
    doubles and I'm having problems with casting them back to floats.

    For example:
    (double)0.1f = 0.1000000014901 1612

    I don't need the accuracy of doubles, but the speed of floats would be
    benificial, but it seems I'm either going to have to write my own math
    functions or just use doubles. For the record my rather basic test,
    which just performed lots of multiplications and divisions, took half
    the time using floats as using doubles.

    Has anyone else had this problem? And can someone give me an efficient
    Floor algorithm so I can write my own floating point version?

    James.

  • James Thurley

    #2
    Re: double or float?


    Michael Mayer wrote:
    [color=blue]
    >
    > I guess I'm curious why you can't cast back to floats? Do you need the
    > precision or not? I have a feeling you're running into this problem:
    >
    > http://www.pobox.com/~skeet/csharp/floatingpoint.html
    > (thanks to Jon Skeet for the article)
    >
    >[/color]

    I don't need double precision, but the inaccuracy caused by casting can
    make, for example, the Floor function give the incorrect answer:

    float min=1.0f, increment=0.1f;
    double result = Math.Floor(min/increment)*incr ement;

    I'm leaving the result as a double in this example - its casting from
    float to double that's causing the problem here. In theory,
    min/increment will be 10.0 which is also the Floor. Multiply it by
    increment and you get 1.0 again. But result comes out as
    0.9000000134110 4507. (Try it - I swear it's true!)

    Now I get that number if I put "Math.Floor(1.0 f/(double)0.1f)*0 .1f" into
    the watch window. Even wierder, If I copy and paste
    "Math.Floor (min/increment)*incr ement" into the watch window it gives me
    the correct answer of 1.0. So I guess the compiler must be making the
    conversion to double earlier than I would have expected, but either way
    it's causing a problem.

    I'm starting to think I should just use doubles... processors of the
    future will be 64bit anyway I guess.


    Comment

    • Justin Rogers

      #3
      Re: double or float?

      The code at the end demonstrates your problem. When casting from a float
      number up to a double, you are getting some slightly skewed results. If you
      divide 1/.1 in float or double you always get 10, however, casting a float
      10 to a double results in some small amount of inaccuracy 9.9999998509883 9.
      Generally you can work this off by using an error quotient or some small
      decimal that gives a degree of freedom. This could be demonstrated by doing
      (float fixedError = .0001f; Math.Floor((min/increment)+fixe dError);) You
      could also make use of the Round function instead of the floor method, or
      you could roll your own floor method for floats.

      using System;

      public class Locality {
      private static void Main(string[] args) {
      float min=1.0f, increment=0.1f;
      double mind=1.0D, incrementd=0.1D ;

      Console.WriteLi ne(min/increment);
      Console.WriteLi ne(mind/incrementd);
      Console.WriteLi ne((double) (min/increment));

      Console.WriteLi ne(Math.Floor(m in/increment));
      Console.WriteLi ne(Math.Floor(m ind/incrementd));

      double result = Math.Floor(min/increment)*incr ement;
      Console.WriteLi ne(result);
      }
      }


      --
      Justin Rogers
      DigiTec Web Consultants, LLC.

      "James Thurley" <newsgroups@jam esthurley.NO__S PAM.com> wrote in message
      news:bira1f$b6h $1@titan.btinte rnet.com...[color=blue]
      >
      > Michael Mayer wrote:
      >[color=green]
      > >
      > > I guess I'm curious why you can't cast back to floats? Do you need the
      > > precision or not? I have a feeling you're running into this problem:
      > >
      > > http://www.pobox.com/~skeet/csharp/floatingpoint.html
      > > (thanks to Jon Skeet for the article)
      > >
      > >[/color]
      >
      > I don't need double precision, but the inaccuracy caused by casting can
      > make, for example, the Floor function give the incorrect answer:
      >
      > float min=1.0f, increment=0.1f;
      > double result = Math.Floor(min/increment)*incr ement;
      >
      > I'm leaving the result as a double in this example - its casting from
      > float to double that's causing the problem here. In theory,
      > min/increment will be 10.0 which is also the Floor. Multiply it by
      > increment and you get 1.0 again. But result comes out as
      > 0.9000000134110 4507. (Try it - I swear it's true!)
      >
      > Now I get that number if I put "Math.Floor(1.0 f/(double)0.1f)*0 .1f" into
      > the watch window. Even wierder, If I copy and paste
      > "Math.Floor (min/increment)*incr ement" into the watch window it gives me
      > the correct answer of 1.0. So I guess the compiler must be making the
      > conversion to double earlier than I would have expected, but either way
      > it's causing a problem.
      >
      > I'm starting to think I should just use doubles... processors of the
      > future will be 64bit anyway I guess.
      >
      >[/color]


      Comment

      • Michael A. Covington

        #4
        Re: double or float?

        > I don't need double precision, but the inaccuracy caused by casting can[color=blue]
        > make, for example, the Floor function give the incorrect answer:
        >
        > float min=1.0f, increment=0.1f;
        > double result = Math.Floor(min/increment)*incr ement;[/color]

        There is no exact representation of 0.1 in binary.


        Comment

        • Jon Skeet

          #5
          Re: double or float?

          Justin Rogers <Justin@games4d otnet.com> wrote:[color=blue]
          > A floating point version of floor? Remember floor is doing nothing more
          > than storing an integer value so the (int) cast is perfect for this
          > operation.[/color]

          Except they do different things for negative numbers - casting to int
          rounds to 0, Floor always rounds down.

          --
          Jon Skeet - <skeet@pobox.co m>
          Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

          If replying to the group, please do not mail me too

          Comment

          • James Thurley

            #6
            Re: double or float?


            Jon Skeet wrote:
            [color=blue]
            > Justin Rogers <Justin@games4d otnet.com> wrote:
            >[color=green]
            >>A floating point version of floor? Remember floor is doing nothing more
            >>than storing an integer value so the (int) cast is perfect for this
            >>operation.[/color]
            >
            >
            > Except they do different things for negative numbers - casting to int
            > rounds to 0, Floor always rounds down.
            >[/color]

            Hmm... I guess something like this should work:

            public int Floor(float val){
            if(val>0.0f || val==(int)val)
            return (int)val; // Positive numbers and negative whole numbers
            else
            return ((int)val) - 1; // Negative floating point numbers
            }

            Not very pretty, but should be fast!


            Comment

            • Oscar Papel

              #7
              Re: double or float?

              > I'm starting to think I should just use doubles... processors of the[color=blue]
              > future will be 64bit anyway I guess.[/color]

              the "bitness" of a CPU has nothing to do with this.
              On a 32 bit CPU a float can be fetched in 1 cycle and a double in 2 cycles
              On a 64 bit CPU 2 floats can be fetched in 1 cycle and a double in 1 cycle

              So the net effect will be the same.
              The only thing that is really a factor is how well the FP units within the
              CPU are implemented.

              If you are really trying to crunch numbers then look at the CPU specific
              SIMD instructions available for your target CPU. Oh, and forget c# since
              the runtime doesn't use them.

              Oscar


              Comment

              Working...