В настоящее время я пишу шаблонный вспомогательный метод, который может преобразовывать числа C в целом (включая unsigned long long) в числа mpz_class в библиотеке GMP. Между ними есть вызов std::abs
.
Однако оказывается, что для C++17 (g++ 6.3.1)
#include <iostream>
#include <cmath>
int main()
{
std::cout << (unsigned long long)std::abs(9484282305798401ull);
}
дает неверный вывод 9484282305798400
.
Как я понял из cmath, std::abs
сначала приводит аргумент к типу double.
Согласно документам C++, double имеет 52 бита мантиссы, а это означает, что максимальное целочисленное значение I должно быть строго меньше 2^52 = 4503599627370496
до какой-либо потери точности.
Правильно ли я говорю, что, поскольку 9484282305798401
превышает этот предел, std::abs
в конечном итоге отбрасывает точность, чтобы дать неверный ответ?
Чтобы уточнить, я абсолютно осознаю, что совершенно бессмысленно запрашивать абсолютное значение целого числа без знака; Однако я хотел бы, чтобы шаблонная функция работала для общих чисел C, вместо того, чтобы специально создавать специализацию для каждого подписанного и неподписанного типа отдельно.
abs
для беззнакового типа? - person stybl   schedule 31.05.2017