std :: abs用于“unsigned long long int”数据类型

时间:2013-06-19 10:37:19

标签: c++ visual-studio-2010

为什么我会收到此错误

 C2668: 'abs' : ambiguous call to overloaded function

对于像这样的简单代码

#include <iostream>
#include <cmath>
int main()
{
  unsigned long long int a = 10000000000000;
  unsigned long long int b = 20000000000000;
  std::cout << std::abs(a-b) << "\n";   // ERROR
  return 0;
}

删除std::后仍会出现错误。但是,如果我使用int数据类型(值较小),则没有问题。

传统的解决方案是手动检查

std::cout << (a<b) ? (b-a) : (a-b) << "\n";

这是唯一的解决方案吗?

4 个答案:

答案 0 :(得分:11)

检查似乎是唯一真正好的解决方案。替代品需要比你的更大的类型和非标准的扩展来使用它。

如果您的范围适合,您可以使用解决方案投射到签署的long long。我几乎不会这样建议,特别是如果将实现放在只执行该功能的函数中。

答案 1 :(得分:5)

您包括<cmath>,因此使用“floating-point abs”。

integer abs”在<cstdlib>中声明。

然而,unsigned long long intab都没有过载,因此a-b也是如此),以及long long int的重载仅存在于C ++ 11之后。

答案 2 :(得分:1)

首先,您需要包含正确的标头。正如gx_所指出的,<cmath>有一个浮点abs,在我的编译器上它实际上是编译的,但结果可能不是你想要的那个:

1.84467e+19

改为包含<cstdlib>。现在错误是:

main.cpp:7:30: error: call of overloaded ‘abs(long long unsigned int)’ is ambiguous
main.cpp:7:30: note: candidates are:
/usr/include/stdlib.h:771:12: note: int abs(int)
/usr/include/c++/4.6/cstdlib:139:3: note: long int std::abs(long int)
/usr/include/c++/4.6/cstdlib:173:3: note: long long int __gnu_cxx::abs(long long int)

正如您所看到的,此函数没有unsigned重载,因为计算unsigned类型的某个值的绝对值是没有意义的。

我看到答案建议您将unsigned类型转换为已签名的类型,但我相信这是 dagereous ,除非您真的知道自己在做什么! 让我先问一下您要操作的值ab的预期范围是多少?如果两者均低于2^63-1,我强烈建议您使用long long int。如果不是这样,请注意你的价值观程序:

a=0, b=1

a=2^64-1, b=0

将生成完全相同的结果,因为实际上需要65位来表示2个64位值差异的任何可能结果。如果您可以确认这不会成为问题,请按照建议使用强制转换。但是,如果您不知道,您可能需要重新考虑您实际想要实现的目标。

答案 3 :(得分:-2)

因为在使用C的C ++之前,你曾经使用过abs,fabs,每个不同类型的实验室,c ++允许abs的重载,在这种情况下,它不理解或不满意你的重载。

使用labs(a-b)看到你正在使用多头,这可以解决你的问题。