Я беру входные данные в двойном формате, а затем типизирую их, чтобы вывести часть дроби. Однако, когда вводится небольшое число, скажем 4294967295.2
часть дроби извлекается, но когда я ввожу большее число, то эта доля дроби становится равной нулю. Я знаю, что это какая-то вещь, но я немного новичок в этом деле. Какова причина получения дробной части в ноль, когда входное число похоже 9007199254740991.2
.? Вот код:
unsigned long long first,second;
double a,b,remainderA,remainderB;
cout << "Enter first number:\n"<< endl;
cin>> a;
cout << "\nEnter second number:\n"<< endl;
cin >> b;
first=(unsigned long long) a;
second=(unsigned long long) b;
remainderA=a-first;
remainderB=b-second;cout<<remainderA<<endl;
С уважением
Это просто вопрос точности. Двойник имеет 52 бита мантиссы, что дает около 15-17 бит десятичных цифр. Ваш второй пример достигает этого предела, и фракция (0.2), скорее всего, не сохраняется в двойном.
Когда число ввода достаточно велико, чтобы соответствовать целевому типу, оно будет приведено к 0. Вы берете ввод в двойном формате, который имеет больший диапазон. и приведение его в беззнаковое длинное длинное, которое имеет меньший диапазон. Вот почему проблема происходит.
Вы можете взглянуть на следующее
http://www.tutorialspoint.com/cprogramming/c_type_casting.htm
double имеет диапазон: 1.7E +/- 308 (15 цифр)
и unsigned long long имеет диапазон: от 0 до 18,446,744,073,709,551,615 (20 цифр)
и вы читаете первым = (без знака длинный длинный) a;
например. если вы вставляете 9007199254740991.2 в «а», то
введенное значение
a = 9,0072e+015
first :90071992547409910
Следовательно это вопрос точности. Вот почему вы получаете проблему.
Числа с плавающей точкой хранят определенное количество цифр. Если число слишком длинное, то дробная часть уже прошла предельную точность типа данных.
Чтобы получить более значимые цифры, чем double
, пытаться long double
, Например, это выводы 0.2
(приблизительно, опять же из-за ограниченной точности): https://ideone.com/i8Yyt0
Вы можете использовать std::floor
для выполнения округления, так как приведение большого числа к целочисленному типу вызывает неопределенное поведение, оно находится вне диапазона целочисленного типа. (Может произойти сбой, как деление целого числа на ноль.)