I am currently writing a template helper method that can convert C numbers as a whole (including unsigned long long) to mpz_class numbers in the GMP library. Between them there is a call to std::abs .
However, it turns out that for C ++ 17 (g ++ 6.3.1),
#include <iostream> #include <cmath> int main() { std::cout << (unsigned long long)std::abs(9484282305798401ull); }
gives an incorrect conclusion 9484282305798400 .
As I understood from cmath , std::abs first passes the argument to double.
According to C ++ docs, double has 52 bits of mantissa, which means that the maximum integer value must be strictly less than 2^52 = 4503599627370496 before losing accuracy.
Is it possible to say that since 9484282305798401 exceeds this limit, std::abs ends the precision cancellation to give the wrong answer?
To clarify, I absolutely understand that it is absolutely not necessary to request the absolute value of unsigned integers; However, I would like the template function to work for C totals, rather than separately creating a specialization for each signed and unsigned type separately.
c ++ floating-point precision c ++ 11 c ++ 17
Yiyuan lee
source share