Страницы

Поиск по вопросам

воскресенье, 9 февраля 2020 г.

Приведение числа double к float с большой точностью

#cpp #float #double


Пусть у меня есть некоторое значение типа double, мне необходимо провести некоторые
манипуляции над этим значением и конвертировать в тип float.
Имею такие данные:

double x = 12058660.309519000;
float xx = x * 0.1f;

когда я проверяю через отладку выражение для переменной xx получаю - 1205866.0309518999,
но когда проверяю само значение переменной xx, то получаю - 1205866.00

Почему?

Мне необходимо сохранить точность.
    


Ответы

Ответ 1



Вы уперлись в точность. Точность float — 7-8 знаков. Это значит, что float может хранить только 7 или 8(нечет и чет соответственно) цифр. Возьмите число с целой частью поменьше(1234, допустим), и у вас останется еще 8-4==4 цифры для дробной части. Точность double(число двойной точности) - 15 знаков. Как можете заметить, double у вас тоже округляется до 15-го знака, причем не после запятой, а вообще. Округление связано с тем, что в памяти компьютера все числа представляются в двоичной системе счисления. Поэтому дробные числа в большинстве своем представляются в виде дроби, а уже она потом округляется, что вы и видите. В float вы не сможете хранить больше 7-8 цифр, повторяю еще раз.

Ответ 2



Проведем простой эксперимент #include #include int main() { float f = 1205866; printf("%.10f\n", f); printf("%.10f .. %.10f\n", nextafterf(f, 0), nextafterf(f, 1e8f)); } Получаем 1205866.0000000000 1205865.8750000000 .. 1205866.1250000000 Это - ближайшие соседние числа, представимые в IEEE 754 типе float. Никакие другие значения в этой окрестности тип float представить не может. То есть ни о каком 1205866.0309518999 не может быть и речи. 1205866 - это ближайшее к вашему 1205866.0309518999 представимое значение типа float. Вот и ответ на ваш вопрос "Почему?". Таким образом вы прекрасно "сохранили точность" - настолько, насколько это вообще возможно в выбранном вами типе. Если вы хотите еще лучше "сохранить точность", то тип float вам тут помочь не сможет. Используйте более точные типы. А если вам абсолютно необходимо конвертировать результат в тип float, то - увы... Например, аналогичный эксперимент с типом double даст нам 1205866.00000000000000000000 1205865.99999999976716935635 .. 1205866.00000000023283064365 Как видите, "шаг" типа double в этой окрестности несравнимо мельче, чем ваше .0309....

Комментариев нет:

Отправить комментарий