Получение неверного абсолютного значения в C ++ / C

0

Я пытаюсь найти абсолютное значение в 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

Значение, которое я получаю для absoluteValue, составляет 4294967294... что неправильно. Ответ также неверен для int. Мне нужно вычислить абсолютное значение несколько раз в коде. Есть ли более эффективный способ достичь этого?

Есть ли эффективный способ найти абсолютное значение для целых чисел?

  • 8
    Абсолютное значение целого числа без знака?
  • 0
    @devnull int предполагается, когда unsigned не имеет определенного типа данных.
Показать ещё 6 комментариев
Теги:

7 ответов

6
Лучший ответ

Вычитая значения unsigned подобные этому, оно может быть завершено.

Если вы хотите получить абсолютное значение unsigned сделайте что-то вроде этого:

unsigned absoluteValue = (value1>value2)?(value1-value2):(value2-value1);undeflow
  • 3
    Формулировка должна быть изменена здесь. Технически, арифметика без знака не переполняется и не «переполняется» из-за того, как она определена. Это обертывания.
  • 0
    Да, этот термин незаконно присваивается для этих случаев.
Показать ещё 4 комментария
1

Прежде всего в C++ такой вызов неоднозначен. Если вы скомпилировали код в C, тогда ваш результат будет равен 6 в обоих случаях. Результат, который вы получили, может получить, если вы сделаете аргумент двойным. Например

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

Сравните два результата вызова функции в следующем фрагменте кода

    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;

Выход будет

absoluteValue = 6, absValue = 6

absoluteValue = 4294967290, absValue = -2147483648

Почему такая разница?

Значение выражения1 - value2 имеет тип unsigned int. Вот арифметика с двумя дополнениями. Тогда функция abs применяется в первом случае выражение преобразуется в подписанный int и будет равно -6 в соответствии с арифметикой с двумя дополнениями. Таким образом, функция возвращает 6 для обеих переменных.

Во втором случае выражение (положительное из-за типа unsigned int) преобразуется в double, а функция возвращает double. Это будет положительное значение, равное 4294967290. Теперь это значение для второй переменной преобразуется в подписанный int, и вы получаете -2147483648

0

Значение cast1 и value2 long long

принять абсолютную величину разницы

затем откройте ответ на неподписанный - он всегда будет соответствовать

0

value1-value2 на самом деле равен 4294967294 в вашей реализации C++, потому что value1 и value2 являются неподписанными и, следовательно, модульными типами.

  • 0
    Итак, как мне найти абсолютное значение их вычитания. Спасибо за ответ
  • 0
    Вы нашли абсолютную ценность вычитания. Абсолютное значение 4294967294 составляет 4294967294.
Показать ещё 2 комментария
0

Вы должны сначала перенести эти значения в integer. Пытаться:

#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));
  • 1
    Это терпит неудачу, если значения не могут быть представлены int .
0

Как насчет этого?

unsigned int abs( int a )
 {
   if( a < 0 )
      return a * (-1);
   return a;
 }
  • 0
    Можно также назвать стандартную библиотеку abs , нет?
  • 0
    Нет. Std :: abs возвращает -6 (я полагаю, вы знаете, почему), что в случае без знака равно 2 ^ 32 - 6, однако приведенный выше код возвращает правильные ответы для примера OP ...
0

Ну, во-первых, вы должны использовать знаковые целые числа, а не unsigned. Тогда это в основном

(a-b)<0 ? -(a-b) : (a-b)

например

int main()
{
    int a=24;
    int b=10;

    unsigned ab=(a-b<0) ? -(a-b) : (a-b);

    printf("%lu\n", ab);
}

Ответ KoKuToru делает это правильно для неподписанных.

  • 0
    Почему вы должны ограничить его целыми числами со знаком? Абсолютная разница (без знака) хорошо определена для чисел без знака.
  • 1
    Ага. Вы правы, и @KoKuToru прибил это.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню