Thread: absolute value of a double

  1. #1
    Registered User
    Join Date
    Apr 2007
    Location
    Greece
    Posts
    52

    absolute value of a double

    I would like an efficient way to get the positive value of a double.
    The obvious way would be:

    Code:
    double absolute(double number)
    {
        if (number < 0)
            return -number;
        else
            return number;
    }
    but I would like something which is faster. I have considered the fact of using a mask on the number (so its first bit - the sign bit according to the IEEE 754 standard - would become 0) but that simply doesn't work on double number. The & doesn't work at all on double numbers.

  2. #2

  3. #3
    Registered User
    Join Date
    Apr 2007
    Location
    Greece
    Posts
    52
    Where can I find what exactly does?
    The best that I have found till now is:
    Code:
      inline float
      fabs(float __x)
      { return __builtin_fabsf(__x); }
    
      inline long double
      fabs(long double __x)
      { return __builtin_fabsl(__x); }
    
      template<typename _Tp>
        inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
    					   double>::__type
        fabs(_Tp __x)
        { return __builtin_fabs(__x); }
    from the cmath.h file, but it wasn't really helpful.

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Err... I think you got your tongue twisted. It's math.h for C and cmath for C++, no cmath.h. (except maybe pre-standard headers, but I'm not sure about that.)

    For standards:

    http://cboard.cprogramming.com/showthread.php?t=84349

    Looking in implementations' implementations for information on what a function is guaranteed to do is not a good idea because the implementation of your implementation may vary from implementation to implementation.
    Last edited by robwhit; 05-17-2008 at 07:51 PM.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You are looking for the absolute value for a real number?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Apr 2007
    Location
    Greece
    Posts
    52
    yes.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I see. I was just wondering.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Apr 2007
    Location
    Greece
    Posts
    52
    So, the moral of this story is that there is no way to apply a mask on an double. Right?
    I tried to cast it and then use a mask but it doesn't work because some digits are truncated.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    In case you need to apply a mask, you can do:
    Code:
    double d = 1.0;
    unsigned long long* x = (unsigned long long*)&d;
    *x |= 0x20;
    Just beware that a double isn't an integral type, so you won't see "1" or anything in *x.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Apr 2007
    Location
    Greece
    Posts
    52
    Code:
    double absolute(double number)
    {
        printf("%f ", number);
        unsigned long long* x = (unsigned long long*)&number;
        *x &= 0x7fffffff;
    
        number = *(double *)x;
        printf("%f \n", number);
        return number;
    }
    It doesn't work. It always returns 0.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
        number = *(double *)x;
    You should not need to do that, since x is a pointer to the original double, the original value is affected. Do not assign.
    The problem is also that a mask designed for integers won't work for doubles, since they are clearly different.
    To use masks on doubles, you'll have to read about how floating point works. It's a little outside my area, though.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    it doesn't work because your mask
    Code:
    0x7fffffff;
    is a little too short ( it's a long literal ).
    Kurt

  13. #13
    Registered User
    Join Date
    Apr 2007
    Location
    Greece
    Posts
    52
    Thanks!
    The solution is:

    Code:
    double absolute(double number)
    {
        //printf("&#37;f ", number);
        unsigned long long* x = (unsigned long long*)&number;
        *x &= 0x7fffffffffffffff;
    
        number = *(double *)x;
        //printf("%f \n", number);
        return number;
    }
    I have run some test and it is faster than the other implementation. The jumps add a complexity because compiler can't decide efficiently what is the next instruction to execute. It's still slower than the implementation of the standard library, though.
    Last edited by myle; 05-18-2008 at 08:34 AM.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Again,
    Code:
    number = *(double *)x;
    This is not necessary!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Apr 2007
    Location
    Greece
    Posts
    52
    Indeed. You are right. Sometimes I am such an idiot.
    My best try so far, still slower than the standard implementation:

    Code:
    double inline absolute(double number)
    {
        //printf("&#37;f ", number);
        unsigned long long* x = (unsigned long long*)&number;
        *x &= 0x7fffffffffffffff;
    
        //printf("%f \n", number);
        return number;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Copying 2-d arrays
    By Holtzy in forum C++ Programming
    Replies: 11
    Last Post: 03-14-2008, 03:44 PM
  2. C++ to C Conversion
    By dicon in forum C Programming
    Replies: 7
    Last Post: 06-11-2007, 08:38 PM
  3. need some help with last part of arrays
    By Lince in forum C Programming
    Replies: 3
    Last Post: 11-18-2006, 09:13 AM
  4. newbie needs help with code
    By compudude86 in forum C Programming
    Replies: 6
    Last Post: 07-23-2006, 08:54 PM
  5. Unknown Math Issues.
    By Sir Andus in forum C++ Programming
    Replies: 1
    Last Post: 03-06-2006, 06:54 PM