Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.87
korez
8 / 8 / 0
Регистрация: 22.02.2011
Сообщений: 182
#1

float переменная - C++

12.06.2011, 08:06. Просмотров 2109. Ответов 14
Метки нет (Все метки)

я инициализирую переменную float значением 0.15 а в действительности там 0.15000001.
потом прибавляю 0.01 получаю 0.16000001
потом прибавляю 0.01 еще раз, получаю 0.17000002.

откуда еще берется 0.00000001 и как от этого избавится?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.06.2011, 08:06
Здравствуйте! Я подобрал для вас темы с ответами на вопрос float переменная (C++):

В программе объявлена переменная float x=2 - C++
Какое значение получит переменная х в результате вычисления х*=(--x+1) подскажите как тут получают ответ... знаю что ++ прибавление а...

Переменная float со значением 1.#QNAN - C++
Здравствуйте! Помогите пожалуйста с такой проблемой. При считывании из файла в переменной типа float оказалось значение 1.#QNAN (показывает...

Переменная float - знаки после запятой - C++
Итак я задаю какую-либо переменную типа float. Потом, с помощью scanf кладу в эту переменную значение 3.2 (к примеру.) Затем, с помощью...

опять ошибка.на этот раз cannot convert `float (*)(float)' to `float' in argument passing - C++
#include<stdio.h> #include<stdlib.h> #include<math.h> float f1(float x)/*vira*enie 1*/ {return (x*cos(x))/(1+ pow(x,2));} ...

Чем отличаются float преобразования (float)var от float(var) - C++
Здравствуйте! Подскажите, чем отличается (float)var от float(var)

invalid types `float[float]' for array subscript - C++
void SEARCH(float vol, float price, int i) { if (i>N) { if(price>maxprice) { ...

14
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
12.06.2011, 08:30 #2
http://democoder.ru/article/14
1
korez
8 / 8 / 0
Регистрация: 22.02.2011
Сообщений: 182
12.06.2011, 08:52  [ТС] #3
pito211, что делать скажи
0
tylix
68 / 55 / 6
Регистрация: 10.06.2011
Сообщений: 149
12.06.2011, 08:57 #4
Цитата Сообщение от pito211 Посмотреть сообщение
Почитал. Интересно. Статья очень полезная.

Но ошибка мне кажется в компиляторе.
0
diagon
Higher
1930 / 1196 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
12.06.2011, 09:13 #5
Цитата Сообщение от korez Посмотреть сообщение
pito211, что делать скажи
Использовать double/GMP
Цитата Сообщение от tylix Посмотреть сообщение
Но ошибка мне кажется в компиляторе.
Тогда это ошибка всех компиляторов=)
Вот простенький код, демонстрирует точность float и double
C
1
2
3
4
5
6
7
#include <cstdio>
int main(){
    float f = 0.1;
    double d = 0.1;
    printf("%.20f \n%.20lf",f,d);
    return 0;
}
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
12.06.2011, 09:38 #6
Цитата Сообщение от tylix Посмотреть сообщение
Но ошибка мне кажется в компиляторе.
"ошибка" если её можно так назвать в системе исчисления. В двоичном виде 0.15 - бесконечная дробь.

Добавлено через 2 минуты
Цитата Сообщение от korez Посмотреть сообщение
pito211, что делать скажи
в статье которую я привёл есть решение. Округлять
0
tylix
68 / 55 / 6
Регистрация: 10.06.2011
Сообщений: 149
12.06.2011, 10:20 #7
Млин... не знал этого... буду учитывать в будущем
0
korez
8 / 8 / 0
Регистрация: 22.02.2011
Сообщений: 182
12.06.2011, 10:28  [ТС] #8
как округлять
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
12.06.2011, 10:44 #9
а чё ты хочешь? При вычислениях от погрешности никуда не денешься, или итерациями пользоваться так точнее, но медленее. При сравнении надо ввести константу эпсилон и сравнивать с какой надо точностью. Но если операций с даблами не слишком много, можно забить на погрешность и при выводе воспользоваться precision, то есть просто обрезать мусор. Чё эта единичка так сильно влияет чтоли на твои мегавычисления?
0
ValeryLaptev
Эксперт С++
1042 / 821 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
12.06.2011, 10:53 #10
Цитата Сообщение от korez Посмотреть сообщение
как округлять
С точностью до эпсилон. А эпсилон - от задачи зависит.
C++
1
t = floor(t+0.5);   // -- до целых округление.
0
Mr.X
Эксперт С++
3051 / 1696 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
12.06.2011, 11:53 #11
В статье http://democoder.ru/article/14, на которую ссылается pito211 в сообщении #2, ошибка в разделе о вычитании:
>>>>>>>>>>>>>>>>>>>>>>>начало цитаты>>>>>>>>>>>>>>>>>>>>>>
VII. Осторожнее с вычитанием!

Это наименее точная операции из всех алгебраических в компьютере. Вы должны избегать её где только возможно, особенно остерегайтесь вычитания очень близких друг к другу чисел, потому что из-за ошибки округления они могут выродиться в 0, а если эта разность была в знаменателе, то нетрудно представить, к чему это приведёт.

Е. Волков приводит интересный пример в своей книге "Численные методы":

"Мы должны вычислить sqrt(543)-sqrt(540), где 543 и 540 даны точно. (то есть все их разряды значащие)

Имеем

sqrt(543) = 23.30....


sqrt(540) = 23.23....

Округлим их до трёх разрядов (потому что столько было в исходных данных, а точность может только уменьшаться)

sqrt(543) - sqrt(540) ~ 23.3 - 23.2 = 0.1

Имеем только один значащий разряд в результате.

Избавимся от вычитания искусственным преобразованием:

sqrt(543) - sqrt(540) = 3 / (sqrt(543)+sqrt(540))

(умножили на sqrt(543)-sqrt(540))

Это равняется 3/(23.3+23.2) = 3/46.5 = 0.0645, мы имеем три значащих разряда в результате."
>>>>>>>>>>>>>>>>>>>конец цитаты>>>>>>>>>>>>>>>>>>>>>>>>>>>

Здесь 3/46.5 = 0.0645 неверно, так как 3 получается вычитанием 543 – 540, где числа даны с точностью до единицы, следовательно тройка имеет только одну значащую цифру, и при делении 3/46.5 мы в полученном результате также имеем право оставить только одну, т.е. в частном 0.0645 все цифры недостоверные, а можно писать только 0.1.
Похоже, что и Е. Волков, на которого там ссылаются, также с математикой не в ладах.
Собственно, в том-то и опасность вычитания, что оно может резко уменьшить количество значащих цифр.
0
grizlik78
Эксперт С++
1966 / 1459 / 120
Регистрация: 29.05.2011
Сообщений: 3,018
12.06.2011, 12:05 #12
Цитата Сообщение от Mr.X Посмотреть сообщение
так как 3 получается вычитанием 543 – 540, где числа даны с точностью до единицы, следовательно тройка имеет только одну значащую цифру
Непонятно, на чём основан данный вывод. По условию 543 и 540 — точные значения, а не округлённые. В результате вычитания тоже получаются точное. Вот если бы 543 и 540 вычислялись бы с точностью до 3 знаков, то данное замечание было бы справедливым. Но в общем согласен, небольшой элемент жульничества тут присутствует
0
korez
8 / 8 / 0
Регистрация: 22.02.2011
Сообщений: 182
12.06.2011, 12:12  [ТС] #13
совершенно верно мне она не нужна эта еденица нужно только четыре знака после, точки как сделать?
0
Mr.X
Эксперт С++
3051 / 1696 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
12.06.2011, 12:12 #14
В общем, автор статьи хотел продемонстрировать вред вычитания, но пример выбрал неудачный, так как вычитание используется в обоих случаях.
0
tylix
68 / 55 / 6
Регистрация: 10.06.2011
Сообщений: 149
12.06.2011, 12:39 #15
Цитата Сообщение от korez Посмотреть сообщение
совершенно верно мне она не нужна эта еденица нужно только четыре знака после, точки как сделать?
В инете нашел это... хотя меня мучают смутные сомнения )

C++
1
2
3
inline double round( double val, double prec) {
    return ((long long)((val/prec) + ((val > 0) ? 0.5 : -0.5)))*prec;
}
0
12.06.2011, 12:39
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.06.2011, 12:39
Привет! Вот еще темы с ответами:

cannot convert `float' to `float*. Почему так происходит? - C++
всем привет, помогите исправить ошибки... а то голова мало варит уже, а завтра надо сдать уже #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt;...

неверное приведение void* к *float а далее к float - C++
Почему когда привожу void* к int* потом к int то все работает, данные не бьются и работают нормально, когда делаю те же операции но с...

Ошибка cannot convert 'float' to 'float*' - C++
Здравствуйте, что означает error: cannot convert 'float' to 'float*' for argument '1' to 'int mas_time(float*, int)'? Из-за чего она...

Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз - C++
Исходники: /* main.cpp */ #include &quot;hider.h&quot; int main(void) { return 0; } /* foo.cpp */


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru