Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ abs(无符号长)有什么意义吗?_C++_C - Fatal编程技术网

C++ abs(无符号长)有什么意义吗?

C++ abs(无符号长)有什么意义吗?,c++,c,C++,C,我遇到了这段代码,顺便说一句,我的分析器报告说这是一个瓶颈: #include <stdlib.h> unsigned long a, b; // Calculate values for a and b unsigned long c; c = abs(a - b); #包括 无符号长a、b; //计算a和b的值 无符号长c; c=abs(a-b); 这一行是否比c=a-b?这两个选项中是否有一个调用未定义或实现定义的行为,以及是否存在其他潜在的陷阱?请注意,C包含在内,而

我遇到了这段代码,顺便说一句,我的分析器报告说这是一个瓶颈:

#include <stdlib.h>

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

c = abs(a - b);
#包括
无符号长a、b;
//计算a和b的值
无符号长c;
c=abs(a-b);

这一行是否比
c=a-b?这两个选项中是否有一个调用未定义或实现定义的行为,以及是否存在其他潜在的陷阱?请注意,C
包含在内,而不是

不,它没有意义

如果你想要不同,使用

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

如果降到零以下,则无符号将返回(效果类似于添加2sizeof(无符号长)*CHAR_位)

如果您要查找两个数字之间的差异,可以编写一个小模板,如下所示

namespace MyUtils {
  template<typename T>
  T diff(const T&a, const T&b) {
    return (a > b) ? (a - b) : (b - a);
  }
}
C++
(来自
cmath

如果您注意到,每个函数的参数和返回类型都是有符号的。因此,如果您将一个无符号类型传递给其中一个函数,就会发生隐式转换
unsigned T1->signed T2->unsigned T1
(在您的情况下,
T1
T2
可能相同,
T1
long
)。将无符号整数转换为有符号整数时,如果无法在有符号类型中表示该行为,则该行为取决于实现

4.7积分转换[conv.Integral]

  • 如果目标类型为无符号,则结果值最小 与源整数全等的无符号整数(模2n,其中n为 用于表示无符号类型的位数)。[注:在 二的补语表示法,这种转换是概念上的和逻辑上的 位模式没有变化(如果没有截断)- 结束说明]
  • 如果目标类型是有符号的,则该值将保持不变(如果可以) 以目标类型(和位字段宽度)表示;否则,, 该值由实现定义

  • 我认为当c=a-b是负数时,如果c是无符号数,c不是准确的答案。使用abs来保证c是一个正数。

    我不知道您是否认为它有意义,但是应用于无符号值的abs()
    肯定会返回传入值以外的值。这是因为
    abs()
    接受一个
    int
    参数并返回一个
    int

    例如:

    #include <stdlib.h>
    #include <stdio.h>
    
    int main(void)
    {
        unsigned u1 = 0x98765432;
        printf("u1 = 0x%.8X; abs(u1) = 0x%.8X\n", u1, abs(u1));
        unsigned long u2 = 0x9876543201234567UL;
        printf("u2 = 0x%.16lX; abs(u2) = 0x%.16lX\n", u2, labs(u2));
        return 0;
    }
    
    如果设置了无符号值的高位,则
    abs()
    的结果不是传递给函数的值

    减法只是分散注意力;如果结果设置了最高有效位,则从
    abs()
    返回的值将不同于传递给它的值


    当您用C++头编译此代码,而不是在问题中显示的C标题时,它不能用模糊的调用错误编译:

    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    int main(void)
    {
        unsigned u1 = 0x98765432;
        cout << "u1 = 0x" << hex << u1 << "; abs(u1) = 0x" << hex << abs(u1) << "\n";
        unsigned long u2 = 0x9876543201234567UL;
        cout << "u2 = 0x" << hex << u2 << "; abs(u2) = 0x" << hex << abs(u2) << "\n";
        return 0;
    }
    
    输出:

    u1 = 0x98765432; abs(u1) = 0x6789abce
    u2 = 0x9876543201234567; abs(u2) = 0x6789abcdfedcba99
    

    <>道德:不要使用C代码头,在C++代码中有C++等价物;使用C++头文件代替.< /P>注意,虽然它对于<代码>未签名的长< /COD>或<代码>未签名的INT/COD>不适用,但它将适用于<代码>未签名的CHAR< <代码>和<代码>未签名的短< /C> >(除了没有人使用的病理系统)。我不知道系统的大小(短)=sisiof(int)。这将比sizeof(int)=sizeof(long)(只是想找个机会来取笑“男人”)
    s/sizeof(unsigned long)/sizeof(unsigned long)*CHAR_BIT
    @TheParamagneticCroissant谢谢:)的系统要病态得多。因为这些值是无符号的,它们不能是负数,所以
    abs()
    这个电话没有意义。但是, Author(<)>代码>在C++中被重载,也可能是宏,所以它对我来说不是100%。它甚至可以是一个采用有符号长的函数,然后根据参数的MSB执行某些操作。什么原因让我们接受不可能为负的绝对值?如果没有,只需删除
    abs()
    调用。无法表示值的unsigned到int的潜在转换是未定义的行为。这种转换也是abs产生差异的唯一情况。@UlrichEckhardt如果
    a=10UL
    b=30UL
    ,正确的答案应该是
    20UL
    ,但是去掉
    abs
    会给我错误的答案。在调用
    abs()
    之前,
    10UL-30UL
    产生
    4294967276UL
    (假设为32位无符号长)。如果
    abs()
    按照它的建议(参见我关于宏/重载的说明),结果也是
    4294967276UL
    。如果你想要20,你必须使用有符号算术,例如
    abs(static\u cast(a)-static\u cast(b))
    。你必须确保这不会产生“未定义的行为”。总之,我建议你使用Mohit Jain的建议,即首先检查哪个更大。对于C++的情况,如果你指的是(学校数学)计算自然数,那么“不正确的答案”可能会发生。如果超出了它们的范围,而不是C++,则未签名的值将被包围,所以它总是肯定的。使用<代码> Author()/代码>不应该改变它的值。尽管代码< >代码> >代码>,但是代码< ABS>代码>应该是C++中的一个重载函数。要么实现没有做到这一点,要么
    abs(int)
    不会成为被选中的重载。我认为,如果只包含
    ,就不会。这只为您提供了标准的C函数。我不知道哪个C++头定义了<代码> Abess()/<代码>的重载。我不知道重载是否包括无符号类型。
    被指定为包含C的
    声明,除了在命名空间
    std
    中,加上
    long abs(long)
    long-long abs(long-long)
    。C++的
    是spe
    #include <stdlib.h>
    #include <stdio.h>
    
    int main(void)
    {
        unsigned u1 = 0x98765432;
        printf("u1 = 0x%.8X; abs(u1) = 0x%.8X\n", u1, abs(u1));
        unsigned long u2 = 0x9876543201234567UL;
        printf("u2 = 0x%.16lX; abs(u2) = 0x%.16lX\n", u2, labs(u2));
        return 0;
    }
    
    u1 = 0x98765432; abs(u1) = 0x6789ABCE
    u2 = 0x9876543201234567; abs(u2) = 0x6789ABCDFEDCBA99
    
    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    int main(void)
    {
        unsigned u1 = 0x98765432;
        cout << "u1 = 0x" << hex << u1 << "; abs(u1) = 0x" << hex << abs(u1) << "\n";
        unsigned long u2 = 0x9876543201234567UL;
        cout << "u2 = 0x" << hex << u2 << "; abs(u2) = 0x" << hex << abs(u2) << "\n";
        return 0;
    }
    
    absuns2.cpp: In function ‘int main()’:
    absuns2.cpp:8:72: error: call of overloaded ‘abs(unsigned int&)’ is ambiguous
         cout << "u1 = 0x" << hex << u1 << "; abs(u1) = 0x" << hex << abs(u1) << "\n";
                                                                            ^
    absuns2.cpp:8:72: note: candidates are:
    In file included from /usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:72:0,
                     from absuns2.cpp:1:
    /usr/include/stdlib.h:129:6: note: int abs(int)
     int  abs(int) __pure2;
          ^
    In file included from absuns2.cpp:1:0:
    /usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:174:3: note: long long int std::abs(long long int)
       abs(long long __x) { return __builtin_llabs (__x); }
       ^
    /usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:166:3: note: long int std::abs(long int)
       abs(long __i) { return __builtin_labs(__i); }
       ^
    absuns2.cpp:10:72: error: call of overloaded ‘abs(long unsigned int&)’ is ambiguous
         cout << "u2 = 0x" << hex << u2 << "; abs(u2) = 0x" << hex << abs(u2) << "\n";
                                                                            ^
    absuns2.cpp:10:72: note: candidates are:
    In file included from /usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:72:0,
                     from absuns2.cpp:1:
    /usr/include/stdlib.h:129:6: note: int abs(int)
     int  abs(int) __pure2;
          ^
    In file included from absuns2.cpp:1:0:
    /usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:174:3: note: long long int std::abs(long long int)
       abs(long long __x) { return __builtin_llabs (__x); }
       ^
    /usr/gcc/v4.9.1/include/c++/4.9.1/cstdlib:166:3: note: long int std::abs(long int)
       abs(long __i) { return __builtin_labs(__i); }
       ^
    
    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    int main(void)
    {
        unsigned u1 = 0x98765432;
        cout << "u1 = 0x" << hex << u1 << "; abs(u1) = 0x" << hex << abs(static_cast<int>(u1)) << "\n";
        unsigned long u2 = 0x9876543201234567UL;
        cout << "u2 = 0x" << hex << u2 << "; abs(u2) = 0x" << hex << abs(static_cast<long>(u2)) << "\n";
        return 0;
    }
    
    u1 = 0x98765432; abs(u1) = 0x6789abce
    u2 = 0x9876543201234567; abs(u2) = 0x6789abcdfedcba99