Пусть у меня есть некоторое значение типа double, мне необходимо провести некоторые манипуляции над этим значением и конвертировать в тип float. Имею такие данные:
double x = 12058660.309519000;
float xx = x * 0.1f;
когда я проверяю через отладку выражение для переменной xx получаю - 1205866.0309518999, но когда проверяю само значение переменной xx, то получаю - 1205866.00
Почему?
Мне необходимо сохранить точность.
Вы уперлись в точность. Точность float — 7-8 знаков. Это значит, что float может хранить только 7 или 8(нечет и чет соответственно) цифр. Возьмите число с целой частью поменьше(1234, допустим), и у вас останется еще 8-4==4 цифры для дробной части.
Точность double(число двойной точности) - 15 знаков. Как можете заметить, double у вас тоже округляется до 15-го знака, причем не после запятой, а вообще. Округление связано с тем, что в памяти компьютера все числа представляются в двоичной системе счисления. Поэтому дробные числа в большинстве своем представляются в виде дроби, а уже она потом округляется, что вы и видите.
В float вы не сможете хранить больше 7-8 цифр, повторяю еще раз.
Проведем простой эксперимент
#include <stdio.h>
#include <math.h>
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....
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости