Пусть у меня есть некоторое значение типа 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...
.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Когда мы создаем переменную int var = 5, все понятно, компьютер берет (выделяет) память 32 бита и записывает туда значение 5 в двоичном виде
Не знаю как удалять студентов из класса ГруппСтуденты добавляются из файла или с помощью функции addStudent
Собираю ANGLE в студии VS2017, под windows, по инструкцииЗадаю конфигурацию x86 (32bit) и генерирую проект для студии с помощью: