I\'ve come across this code, which incidentally my profiler reports as a bottleneck:
#include
unsigned long a, b;
// Calculate values for a and
No, it doesn't make sense.
If you want the difference, use
c = (a > b) ? a - b : b - a;
or
c = max(a, b) - min(a, b);
Unsigned if go below zero would wrap back (effect is similar to adding 2sizeof (unsigned long) * CHAR_BIT)
If you are looking for difference between two numbers, you can write a small template as below
namespace MyUtils {
template
T diff(const T&a, const T&b) {
return (a > b) ? (a - b) : (b - a);
}
}
Looking at the declaration of abs inherited from C
(Because you included stdlib.h
)
int abs( int n );
long abs( long n );
long long abs( long long n ); // (since C++11)
//Defined in header
std::intmax_t abs( std::intmax_t n ); // (since C++11)
And abs in C++
(from cmath
)
float abs( float arg );
double abs( double arg );
long double abs( long double arg );
If you notice, both the argument and return type of each function are signed
. So if you pass an unsigned type to one of these function, implicit conversion unsigned T1 -> signed T2 -> unsigned T1
would take place (where T1
and T2
may be same and T1
is long
in your case). When you convert an unsigned integral to signed integral, the behavior is implementation dependendent if it can not be represented in a signed type.
From 4.7 Integral conversions [conv.integral]
- If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). — end note]
- If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.