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

时间:2021-06-04 16:43:21

Why should I get this error

我为什么要收到这个错误

 C2668: 'abs' : ambiguous call to overloaded function

For a simple code like this

对于像这样的简单代码

#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;
}

The error still presents after removing std::. However if I use int data type (with smaller values) there is no problem.

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

The traditional solution is to check that manually

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

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

Is that the only solution?

这是唯一的解决方案吗?

4 个解决方案

#1


10  

The check seem the only really good solution. Alternatives require type bigger than yours and nonstandard extension to use it.

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

You can go with solutions casting to signed long long if your range fits. I would hardly suggest that way, especially if the implementation is placed in a function that does only that.

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

#2


5  

You are including <cmath> and thus using the "floating-point abs".

你包括 ,因此使用“浮点abs”。

The "integer abs" is declared in <cstdlib>.

“整数abs”在 中声明。

However, there is no overload for unsigned long long int (both a and b are, thus a-b is, too), and the overload for long long int only exists since C++11.

但是,无符号long long int没有重载(a和b都是,因此a-b也是如此),long long int的重载仅存在于C ++ 11之后。

#3


1  

First, you need to include the correct header. As pointed out by gx_, <cmath> has a floating-point abs and on my compiler it actually compiles, but the result is probably not the one you expected:

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

1.84467e+19

Include <cstdlib> instead. Now the error is:

请改为包含 。现在的错误是:

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)

As you can see, there is no unsigned overload of this function, because computing an absolute value of something which is of type unsigned makes no sense.

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

I see answers suggesting you to cast an unsigned type to a signed one, but I believe this is dagereous, unless you really know what you are doing! Let me ask first what is the expected range of the values a and b that you are going to operate on? If both are below 2^63-1 I would strongly suggest to just use long long int. If that is not true however, let me note that your program for the values:

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

a=0, b=1

and

a=2^64-1, b=0

will produce exactly the same result, because you actually need 65 bits to represent any possible outcome of a difference of 2 64-bit values. If you can confirm that this is not going to be a problem, use the cast as suggested. However, if you don't know, you may need to rethink what you are actually trying to achieve.

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

#4


-2  

Because back before C++ with C you used to have use abs, fabs, labs for each different type, c++ allows overloading of abs, in this case it doesn't understand or isn't happy with your overload.

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

Use labs(a-b) seeing as you're using longs, this should solve your problem.

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

#1


10  

The check seem the only really good solution. Alternatives require type bigger than yours and nonstandard extension to use it.

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

You can go with solutions casting to signed long long if your range fits. I would hardly suggest that way, especially if the implementation is placed in a function that does only that.

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

#2


5  

You are including <cmath> and thus using the "floating-point abs".

你包括 ,因此使用“浮点abs”。

The "integer abs" is declared in <cstdlib>.

“整数abs”在 中声明。

However, there is no overload for unsigned long long int (both a and b are, thus a-b is, too), and the overload for long long int only exists since C++11.

但是,无符号long long int没有重载(a和b都是,因此a-b也是如此),long long int的重载仅存在于C ++ 11之后。

#3


1  

First, you need to include the correct header. As pointed out by gx_, <cmath> has a floating-point abs and on my compiler it actually compiles, but the result is probably not the one you expected:

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

1.84467e+19

Include <cstdlib> instead. Now the error is:

请改为包含 。现在的错误是:

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)

As you can see, there is no unsigned overload of this function, because computing an absolute value of something which is of type unsigned makes no sense.

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

I see answers suggesting you to cast an unsigned type to a signed one, but I believe this is dagereous, unless you really know what you are doing! Let me ask first what is the expected range of the values a and b that you are going to operate on? If both are below 2^63-1 I would strongly suggest to just use long long int. If that is not true however, let me note that your program for the values:

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

a=0, b=1

and

a=2^64-1, b=0

will produce exactly the same result, because you actually need 65 bits to represent any possible outcome of a difference of 2 64-bit values. If you can confirm that this is not going to be a problem, use the cast as suggested. However, if you don't know, you may need to rethink what you are actually trying to achieve.

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

#4


-2  

Because back before C++ with C you used to have use abs, fabs, labs for each different type, c++ allows overloading of abs, in this case it doesn't understand or isn't happy with your overload.

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

Use labs(a-b) seeing as you're using longs, this should solve your problem.

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