Does abs(unsigned long) make any sense?

后端 未结 3 1210
梦毁少年i
梦毁少年i 2021-02-04 05:37

I\'ve come across this code, which incidentally my profiler reports as a bottleneck:

#include 

unsigned long a, b;
// Calculate values for a and         


        
3条回答
  •  一个人的身影
    2021-02-04 05:52

    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]

    1. 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]
    2. 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.

提交回复
热议问题