Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.02.2009, 19:24   #1
HunterMan
Пользователь
 
Регистрация: 01.04.2008
Сообщений: 58
По умолчанию Точность типа float

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

Проблема вот в чем. Например, происходит елементарный перещет:

float a = 1;

for(a;a<10;a+=0.2)
{
cout<<a;
}

Вместо того, чтобы выводить 1, 1.2, 1.4, 1.6... Начинает выводить так:
1, 1.2, 1.4, 1.6, 1.799999, 1.99999

Вопрос: Куда деваются эти миллионные доли числа и как с этим бороться?

Пишу на .NET. Числа берутся с формы и происходят похожие математические общеты. Потом эти числа выводятся на график. Мне нужно чтоб было 1.8, а оно вдает 1.799999. Работаю с типом флоат ибо в .NET есть тип PointF... Я сберигаю ети числа в масиве данного типа, а потом вывожу на экран.
Может стоит работать с double, а потом преобразовывать в float, или... Подскажите какой-то выход плиз.
HunterMan вне форума Ответить с цитированием
Старый 07.02.2009, 19:37   #2
Goblin
Форумчанин
 
Регистрация: 24.11.2007
Сообщений: 196
По умолчанию

перед cout<<a;

Код:
cout.setf(ios::fixed);
cout.setf(showpoint);
cout.precision(2); // Где 2 количество знаков после запятой.
P.S. Источник: Уолтер Савич "Программирование на С++", советую почитать.

Последний раз редактировалось Goblin; 07.02.2009 в 19:39. Причина: Реклама
Goblin вне форума Ответить с цитированием
Старый 07.02.2009, 19:46   #3
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Можно проще. Когда выводите пишете вот так
Код:
std::cout<<std::fixed<<std::setprecision(2)<<a;
Тоже два знака после запятой, только все делается "на лету".
MaTBeu вне форума Ответить с цитированием
Старый 07.02.2009, 20:36   #4
HunterMan
Пользователь
 
Регистрация: 01.04.2008
Сообщений: 58
По умолчанию

Походу вы меня не поняли или я не понял вас.
Этот пример я привел чисто для того, чтобы обьяснить суть проблемы и как приблизительно!!! она получается.

1. пишу на шарпе, значения принимаются с формы, обрабатываются и выводятся на форму с помощью DrawString....
2. Важно!!! не применять какие-либо либо математические преобразования и тем более форматированый способ вывода на экран. Пишется программа эммулирующая протекание тех. процессов в энергетике. Потому точность важна!
3. Мне важен резутьтат! Т.е. если на бумажке я прощитал и вышло 1.8, то и на форму должно вывестись 1.8 а не 1.799999. Потому что выводимые числа могут быть такими к примеру: 0.0077... И никак не должно вывестись 0.0076999. Вот чего я боюсь. Т.е. 1.79999 или 799.9999 я могу привести к 1.8 и 800, а что делать с 0.0076999? Можна алгоритм разработать который будет проверять числа и исправлять, но это явно усложнит код. Можна расчеты проводить в двоичном виде, но каждый выводимый график может иметь миллион или два миллиона значений прощитаных... Прикиньте для каждого анализировать полученый результат???!!!

Потому думаю, что проблема все же в преобразовании типов или с чем-то похожим. Но как исправить... Может перед кем-то стояла похожая проблема?

П.С. Если кто-то подскажет как с этим борится к примеру MatLab или MathCad или Exel или другие программы работающие с графиками и трендами - буду благодарен.
HunterMan вне форума Ответить с цитированием
Старый 07.02.2009, 21:39   #5
capta1n
Форумчанин
 
Аватар для capta1n
 
Регистрация: 06.12.2008
Сообщений: 613
По умолчанию

вещественная арифметика в машине не точна - это значит, что сложив 1000 раз число 0.001 вы никогда не получите ровно 1 ( единицу ) - всегда будут погрешности в вычислении - это связано с внутренним представлением вещественных чисел в машине; точность float - 38 знаков после запятой; из курса математики известно, что 0.8 можно представить как 0.800000... и 0.799999... - это одно и то же- попробуйте выполнить преобразование из десятичной дроби с натуральную: восьмерка обеспечена но я думаю надо просто на выходе ограничить количество выводимых знаков после запятой, тогда вывести должен нормальное число, а так естественно он выводит вплоть до последнего знака всеми девятками

Последний раз редактировалось capta1n; 08.02.2009 в 16:04.
capta1n вне форума Ответить с цитированием
Старый 07.02.2009, 21:49   #6
capta1n
Форумчанин
 
Аватар для capta1n
 
Регистрация: 06.12.2008
Сообщений: 613
По умолчанию

Код:
a;a<10;a+=0.2
и вот в этой строчке начиная с приращения у вас тип float теряется и превращается в стандартный тип double для вещественных чисел - надо явно приводить к одному типу, потому что у вас число 0.2 имеет тип double, а не float ( так есть по стандарту языка ), поэтому надо писать
Код:
a+=0.2f
capta1n вне форума Ответить с цитированием
Старый 07.02.2009, 23:05   #7
HunterMan
Пользователь
 
Регистрация: 01.04.2008
Сообщений: 58
По умолчанию

Умная мысль! Щас проверю!
HunterMan вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Точность при переходе от миллиметров к пунктам viter.alex Microsoft Office Word 2 03.02.2009 16:36
точность вывода переменной XeN0N Помощь студентам 6 21.01.2009 16:30
Точность Sour Помощь студентам 2 31.05.2007 21:08