absolute value of a double

This is a discussion on absolute value of a double within the C Programming forums, part of the General Programming Boards category; Compiler libraries are usually written by people much smarter than you or I, and optimized like crazy. So unless you ...

  1. #16
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Compiler libraries are usually written by people much smarter than you or I, and optimized like crazy. So unless you think you're in the same league as them, I'd stick to the standard library for most things.

  2. #17
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Assuming you are using the cdecl calling convention on a x86-32 processor and working on a compiler who accepts this kind of syntax, by keeping the same function header, your function could looks like this
    Code:
    double absolute(double number)
    {
        _asm
        {
    	    btr dword ptr [ebp + 12], 31
    	    fld qword ptr [ebp + 8]
        }
    }
    Of course, this is quite silly. It makes quite a bit of assumption and i don't think i would ever use this kind of code in a "real" program. If you want something "faster" than this (why you would actually want something faster is another question), then you should change your function prototype to something like "void absolute(double *number)".
    I hate real numbers.

  3. #18
    Registered User
    Join Date
    Apr 2007
    Location
    Greece
    Posts
    52
    An explanation here would be more useful than the solution or at least a hint were I can find some more info. Furthemore, as it is, it doesn't compile on gcc.

    off topic:
    @cpjust: Doing something silly is a privilege that experts don't have, so I like giving it a chance even though I know the odds are against me.

  4. #19
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    > An explanation here would be more useful than the solution or at least a hint were I can find some more info. Furthemore, as it is, it doesn't compile on gcc.

    > It makes quite a bit of assumption
    The assumption is that it's a IEEE-double (The machine might not be) -- that is, 1 bit for the sign, followed by 11 bits for the exponent and the remaining 52 bits for the mantissa. See http://en.wikipedia.org/wiki/IEEE_fl...point_standard for more info.

    Usually with speed comes complexity, not sure if 2 or 3 instructions more is going to be that bad. Leave this optimization upto the compiler

    The 'fastest way' will probably be:

    Code:
    #define ABS_STUPID(n) (n & 0x7fffffffffffffffull)
    
    /* ... */
    
    double test = -908.4, absTest = 0.0;
    
    absTest = ABS_STUPID(test);
    Last edited by zacs7; 05-18-2008 at 10:38 PM.

  5. #20
    Registered User
    Join Date
    Apr 2007
    Location
    Greece
    Posts
    52
    You can't use the & operator on doubles.

  6. #21
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Correct me if I'm wrong but you can't have operands of type "double" with the binary & operator, so the example you just gave actually isn't valid.
    I don't see any way to make this kind of macro works since at the end, the expression will always have the shape of something like "double = unsigned long long" and the implicit conversion will not preserve the binary pattern of the unsigned long long value.

    So, i guess the "fastest way" is probably something like a macro written in assembly ?

    @myle: I won't give a full explanation about the code snippet of my last post but you basically need 3 things to understand it:

    You should also look for this http://en.wikipedia.org/wiki/X86_cal...ces_for_C_code

    EDIT: Oops, too slow.
    Last edited by foxman; 05-19-2008 at 08:41 AM.
    I hate real numbers.

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Also note that if you perform such "tricks" involving moving data from the FPU to integer unit and back to the FPU, then you will most likely incur sever penalties in the performance of the CPU. It may seem that there's fewer instructions involved, but it's actually wasting CPU time shuffling the data about instead - although that is harder to identify.

    The exact penalty of course depends on the circumstances.

    One of the best implementations is probably:
    Code:
    #define ABS(x) ((x) < 0)?-(x):(x)
    The compiler should be able to re-organize that into a minimal number of instructions and if it's reasonably good compiler also avoid the branches that you'd get from the if-statement. Since x is unchanged in the second half, it is "no change", but there is a compare in there.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Posts
    306
    Quote Originally Posted by matsp
    One of the best implementations is probably:
    Code:
    #define ABS(x) ((x) < 0)?-(x):(x)
    Another great advantage of this solution is that is does not depend on any particular floating-point implementation on the machine. It is more portable than the others given. Also, it is a lot easier to think of; I'm surprised no one mentioned it before. Anyways, fabs() is the way to go unless you are just tinkering around.
    GCC on Fedora Core 10

  9. #24
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MacNilly View Post
    Another great advantage of this solution is that is does not depend on any particular floating-point implementation on the machine. It is more portable than the others given. Also, it is a lot easier to think of; I'm surprised no one mentioned it before. Anyways, fabs() is the way to go unless you are just tinkering around.
    Yes, fabs() is most likely very efficient too, since most compilers will have it as an "intrinsic" function, meaning that it's implemented directly in the compiler (rather than as a library function that is called from the code) and it will be highly optimized that way.

    Also, you have to do some pretty weird floating point on a modern processor to actually get poor performance from fabs().

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Page 2 of 2 FirstFirst 12
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, 08: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, 05:54 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21