Home > Blockchain >  For what values would accessing single bytes for XOR logic work faster than multiplication to find i
For what values would accessing single bytes for XOR logic work faster than multiplication to find i

Time:10-06

For checking whether two numbers have the same sign:

#define same_sign(a,b) ((a)*(b)>=0)

but this can also be done with:

#define INTEL_REVERSED//example define specifying whether variables are stored in memory in reverse

#ifdef INTEL_REVERSED
    #define same_sign(a,b) ((~(*((char*)&a sizeof(a)-1)^*((char*)&b sizeof(b)-1))&0x80)>>7)
#else
    #define same_sign(a,b) ((~(*(char*)&a^*(char*)&b)&0x80)>>7)
#endif

Multiplication has time complexity of in between O(n log n) and O(n^2) (when the number is bigger than 4 bytes), while logic always takes the same amount of time. When would the second implementation work faster than the first? Also, I understand that the second one doesn't work on expressions, but only on variables and that for the second one it's possible to put any any data-type, not just integral ones and that first requires integral types(double and float included).

Edit: I've found an error in the first code(I'm suprised that nobody pointed this out): instead of >, there should have been a >=.

CodePudding user response:

The multiplication method is as slow as you might expect, but it is risky: it has undefined behavior if there is an overflow, which is not unlikely for a multiplication, eg: same_sign(-50000, -50000).

Instead of the complicated, system specific macro posted, you can use this simple method:

static inline int same_sign(int a, int b) { return (a ^ b) >= 0; }

If you really want a macro to handle integer types int, long and long long with a single expression, use this:

#define same_sign(a, b) (((a) ^ (b)) >= 0)

The above solutions work for two's complement representation of signed integers. Other representations will have false positives, but you are unlikely to encounter such oddities and support for these will be removed from the next version of the C Standard.

For floating point values, you should use this instead:

#include <math.h>
#define same_sign(a, b) (signbit(a) == signbit(b))

Note that you can write a macro that will work for all non complex number types and should compile to efficient code:

#define same_sign(a, b) (((a) < 0) == ((b) < 0))
  • Related