简体   繁体   English

在C ++ / C中获得错误的绝对值

[英]Getting wrong absolute value in C++/C

I am trying to find the absolute value in C++ by the following method: 我试图通过以下方法在C ++中找到绝对值:

#include <cmath>
unsigned value1=4;
unsigned value2=10;

unsigned absoluteValue=abs(value1-value2);
int absValue=abs(value1-value2);

Answer: absoluteValue=4294967294
        absValue=-2147483648

Desired Answer=6

The value that I am getting for absoluteValue is 4294967294...which is wrong. 我为absoluteValue获得的值是4294967294 ...这是错误的。 The answer is also wrong for int. 答案对于int也是错误的。 I need to compute the absolute value several times in code..is there a more efficient way to achieve this? 我需要在代码中多次计算绝对值。是否有更有效的方法来实现这一目标?

Is there an efficient way to find absolute value for integers? 有没有一种有效的方法来找到整数的绝对值?

By subtract unsigned values like this, it might wrap. 通过减去这样的unsigned值,它可能会自动换行。

If you want to get the absolute value of a unsigned do something like this: 如果要获取unsigned的绝对值,请执行以下操作:

unsigned absoluteValue = (value1>value2)?(value1-value2):(value2-value1);undeflow

First of all in C++ such call is ambiguous. 首先,在C ++中,这样的调用是模棱两可的。 If you compiled the code in C then your result shall be equal to 6 in the both cases. 如果您使用C编译代码,则两种情况下的结果均应等于​​6。 The result you got can be get if you will cast the argument to double. 如果将参数转换为double,则可以得到结果。 For example 例如

    absValue = std::abs( double( value1 -value2 ) );
    std::cout << "absoluteValue = " << absoluteValue << ", absValue = " << absValue << std::endl;

Compare two results of the function call in the following code snippet 在下面的代码片段中比较函数调用的两个结果

    unsigned value1 = 4;
    unsigned value2 = 10;

    unsigned absoluteValue = std::abs( int( value1-value2 ) );
    int absValue = std::abs( int( value1 -value2 ) );
    std::cout << "absoluteValue = " << absoluteValue << ", absValue = " << absValue << std::endl;
    std::cout << std::endl;

    absoluteValue = std::abs( double( value1-value2 ) );
    absValue = std::abs( double( value1 -value2 ) );
    std::cout << "absoluteValue = " << absoluteValue << ", absValue = " << absValue << std::endl;
    std::cout << std::endl;

The output will be 输出将是

absoluteValue = 6, absValue = 6

absoluteValue = 4294967290, absValue = -2147483648

Why is there such a difference? 为什么会有这样的差异?

Expression value1 - valu2 has type unsigned int. 表达式value1-valu2的类型为unsigned int。 Here is two-complement arithmetic. 这是二补码算法。 Then function abs is applied in the first case the expression is converted to signed int and will be equal to -6 according to the two-complement arithmetic. 然后在第一种情况下应用函数abs,将表达式转换为有符号的int,根据双补码算法,该表达式等于-6。 So function will return 6 for the both variable. 因此,函数将为两个变量返回6。

In the second case the (positive due to the type unsigned int) expression is converted to double and the function returns a double. 在第二种情况下,(由于类型为unsigned int而为正)表达式被转换为double,并且该函数返回double。 It will be a positive value equal to 4294967290. Now this value for the second variable is converted to signed int and you get -2147483648 这将是一个等于4294967290的正值。现在,第二个变量的此值将转换为有符号的int,您将获得-2147483648

实际上,在您的C ++实现中, value1-value2等于4294967294,因为value1value2是无符号的,因此是模类型。

Well, first off, you should be using signed integers, not unsigned. 好吧,首先,您应该使用带符号的整数,而不是无符号的整数。 Then it's basically 那基本上是

 
 
 
  
  (ab)<0 ? -(ab) : (ab)
 
  

eg 例如

 
 
 
  
  int main() { int a=24; int b=10; unsigned ab=(ab<0) ? -(ab) : (ab); printf("%lu\\n", ab); }
 
  

KoKuToru's answer does this right for unsigned. KoKuToru的答案适用于未签名的情况。

You have to cast these values to integer first. 您必须先将这些值强制转换为整数。 Try: 尝试:

#include <cmath>
unsigned value1=4;
unsigned value2=10;

unsigned absoluteValue=abs(static_cast<int>(value1)-static_cast<int>(value2));
int absValue=abs(static_cast<int>(value1)-static_cast<int>(value2));

What about this? 那这个呢?

unsigned int abs( int a )
 {
   if( a < 0 )
      return a * (-1);
   return a;
 }

Cast value1 and value2 to long long 将value1和value2强制转换为long long

take absolute value of difference 取差的绝对值

then cast answer back to unsigned - it will always fit 然后将答案投射回无符号-它将始终适合

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM