Abs(无符号长整数)有意义吗? [英] Does abs(unsigned long) make any sense?

查看:41
本文介绍了Abs(无符号长整数)有意义吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了这段代码,我的探查器偶然将其报告为瓶颈:

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

#include <stdlib.h>

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

c = abs(a - b);

那行比 c = a-b; 更有趣吗?这两个选项是否调用未定义的行为或实现定义的行为,还有其他潜在陷阱吗?请注意,包含了C < stdlib.h> ,而不是< cstdlib> .

Does that line do anything more interesting that c = a - b;? Do either of the options invoke undefined or implementation-defined behaviour, and are there other potential gotchas? Note that the C <stdlib.h> is included, not <cstdlib>.

推荐答案

不,这没有道理.

如果您希望有所不同,请使用

If you want the difference, use

c = (a > b) ? a - b : b - a;

c = max(a, b) - min(a, b);

如果小于零,则无符号会回卷(效果类似于添加2 sizeof(无符号长)* CHAR_BIT )

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<typename T>
  T diff(const T&a, const T&b) {
    return (a > b) ? (a - b) : (b - a);
  }
}


查看从 C继承的 abs 的声明(因为您包含了 stdlib.h )

int       abs( int n );
long      abs( long n );
long long abs( long long n ); //    (since C++11)
//Defined in header <cinttypes>
std::intmax_t abs( std::intmax_t n ); //    (since C++11)

C ++ 中的 abs (来自 cmath )

float       abs( float arg );
double      abs( double arg );
long double abs( long double arg );

如果您注意到,则每个函数的参数和返回类型均带有签名.因此,如果将无符号类型传递给这些函数之一,则隐式转换 unsigned T1->签名的T2->将会发生无符号的T1 (其中 T1 T2 可能相同,而 T1 long 您的情况).将无符号积分转换为有符号积分时,如果不能用有符号类型表示,则行为取决于实现.

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.

来自 4.7个整体转化[conv.integral]

  1. 如果目标类型是无符号的,则结果值是最小的与源整数一致的无符号整数(取模2 n ,其中n为用于表示无符号类型的位数).[注意:两个补码表示法,这种转换是概念上的,位模式没有变化(如果没有截断).-尾注]
  2. 如果目标类型是带符号的,则该值可以保持不变以目标类型(和位域宽度)表示;除此以外,该值是实现定义的.
  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.

这篇关于Abs(无符号长整数)有意义吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆