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.
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.
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
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)".Code:double absolute(double number) { _asm { btr dword ptr [ebp + 12], 31 fld qword ptr [ebp + 8] } }
I hate real numbers.
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.
> 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.
You can't use the & operator on doubles.
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:
- To know what is assembly language
- To know the x86-32 instruction set architecture (look for the volumes 2)
- To know about the cdecl calling convention
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.
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:
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.Code:#define ABS(x) ((x) < 0)?-(x):(x)
--
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.
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.Originally Posted by matsp
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.