Извлечение дробной части из двойника в переполнении стека

Я беру входные данные в двойном формате, а затем типизирую их, чтобы вывести часть дроби. Однако, когда вводится небольшое число, скажем 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;

С уважением

0

Решение

Это просто вопрос точности. Двойник имеет 52 бита мантиссы, что дает около 15-17 бит десятичных цифр. Ваш второй пример достигает этого предела, и фракция (0.2), скорее всего, не сохраняется в двойном.

2

Другие решения

Когда число ввода достаточно велико, чтобы соответствовать целевому типу, оно будет приведено к 0. Вы берете ввод в двойном формате, который имеет больший диапазон. и приведение его в беззнаковое длинное длинное, которое имеет меньший диапазон. Вот почему проблема происходит.

Вы можете взглянуть на следующее

http://www.tutorialspoint.com/cprogramming/c_type_casting.htm

0

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

Следовательно это вопрос точности. Вот почему вы получаете проблему.

0

Числа с плавающей точкой хранят определенное количество цифр. Если число слишком длинное, то дробная часть уже прошла предельную точность типа данных.

Чтобы получить более значимые цифры, чем double, пытаться long double, Например, это выводы 0.2 (приблизительно, опять же из-за ограниченной точности): https://ideone.com/i8Yyt0

Вы можете использовать std::floor для выполнения округления, так как приведение большого числа к целочисленному типу вызывает неопределенное поведение, оно находится вне диапазона целочисленного типа. (Может произойти сбой, как деление целого числа на ноль.)

0
По вопросам рекламы [email protected]