Форум программистов, компьютерный форум CyberForum.ru

Глюк при заполнении массива - C++

Восстановить пароль Регистрация
 
Петр91
4 / 4 / 1
Регистрация: 17.05.2010
Сообщений: 108
21.06.2011, 15:33     Глюк при заполнении массива #1
Заполняю массив
Код
float row[501]
float j=0;
for (int i=0;i<501;i++)
{
     row[i]=j;
     cout<<j<<endl;
     j += 0.02;
}
Массив заполняется числами: 0;0.02;0.04 но в середи и конце вылезают такие числа как: 6.24;6.25999;6.27999. Так чисел сорок, потом нормально и опять: 8.52001; 8.54001 в чем дело?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nursik77
 Аватар для Nursik77
273 / 233 / 21
Регистрация: 05.04.2011
Сообщений: 645
21.06.2011, 15:35     Глюк при заполнении массива #2
C++
1
float row[501]
А вы тут точку с запятой случайно забыли?
mimicria
return (true);
 Аватар для mimicria
1956 / 1093 / 91
Регистрация: 19.04.2011
Сообщений: 2,344
21.06.2011, 15:37     Глюк при заполнении массива #3
C++
1
cout<<FormatFloat("0.00",j).c_str()<<endl;
Или так
C++
1
2
3
4
5
6
...
float j=0;
cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);
for (int i=0;i<501;i++)
...
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
21.06.2011, 15:44     Глюк при заполнении массива #4
погрешность накопилась
Петр91
4 / 4 / 1
Регистрация: 17.05.2010
Сообщений: 108
21.06.2011, 15:45  [ТС]     Глюк при заполнении массива #5
Мне не просто вывести надо, а потом еще сравнивать элементы массива!
Код
float row[501];
float j=0;
for (int i=0;i<501;i++)
{
     row[i]=j;
     cout<<j<<endl;
     j += 0.02;
}
if (row[0]==0)
   cout<<"Win!";    -   Выводит Win;

if (row[1]==0.02)
   cout<<"Win!";   - НЕ  выводит ниче
Вопрос, что не так? Погрешность? а почему 0.02 не равно 0.02 это второй элемент всего! Пишу в VS 2010
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
21.06.2011, 15:48     Глюк при заполнении массива #6
округлять, без округления бесполезно double сравнивать
Daemon025
 Аватар для Daemon025
380 / 329 / 67
Регистрация: 06.12.2010
Сообщений: 900
21.06.2011, 15:49     Глюк при заполнении массива #7
замените float на double
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
21.06.2011, 15:51     Глюк при заполнении массива #8
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
float row[501];
float j = 0.0f;
 
for (int i = 0; i < 501; i++ )
{
   row[i] = j;
   cout << j << endl;
   j += 0.02f;
}
 
if ( row[0] == 0.0f )
   cout << "Win!";
 
if ( row[1] == 0.02f )
   cout << "Win!";
Обратите внимание на синтаксис 0.02f. Буква f означает, что это число имеет тип float. При явном указании типа исключаются ошибки при преобразовании типов (потому, что преобразование как таковое не требуется).
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
21.06.2011, 15:56     Глюк при заполнении массива #9
talis, проблема же не в преобразовании, а в том, что большинство конечных в десятичной форме дробей при двоичной записи становятся бесконечными и их просто невозможно точно представить ни числом float, ни double...
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
21.06.2011, 15:57     Глюк при заполнении массива #10
grizlik78, вы скомпилируйте и сравните вариант автора и мой. Проблема-то ушла.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
21.06.2011, 15:59     Глюк при заполнении массива #11
ну да, только автору следует учесть, что он просто отложил проблему
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
21.06.2011, 16:04     Глюк при заполнении массива #12
Скомпилировал. Сравнил. Абсолютно одинаковый результат.
Петр91
4 / 4 / 1
Регистрация: 17.05.2010
Сообщений: 108
21.06.2011, 16:06  [ТС]     Глюк при заполнении массива #13
Заменил float на double вывел массив, все ок! Даже сравнивает правильно целые числа! ноль, один, пять. А вот с дробными проблема! Если писать row[]=0.02 не сравнивает, а через запятую row[]=0,02 понимает.. Шо за фигня...
Сделал как talsi говорит float j=0.0f; Все равно погрешность появляется.
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
21.06.2011, 16:07     Глюк при заполнении массива #14
Цитата Сообщение от Петр91 Посмотреть сообщение
Если писать row[]=0.02 не сравнивает, а через запятую row[]=0,02
Если писать действительно = то это ни разу не сравнение.
А если сравнивать с 0,02, то это эквивалентно просто двойке
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
21.06.2011, 16:09     Глюк при заполнении массива #15
Цитата Сообщение от grizlik78 Посмотреть сообщение
Скомпилировал. Сравнил. Абсолютно одинаковый результат.
C::B 10.05 w/ gcc version 4.4.1 (TDM-2 mingw32)
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
21.06.2011, 16:11     Глюк при заполнении массива #16
talis, gcc 4.5.1 linux/x86_64
От компилятора зависит, согласен, но тем более так нельзя
Петр91
4 / 4 / 1
Регистрация: 17.05.2010
Сообщений: 108
21.06.2011, 16:13  [ТС]     Глюк при заполнении массива #17
в попыхах написал, двойное равно конечно. Делал я как talis float j=0.0f; все равно погрешность есть
row[1]==0,02 - истина
row[0]==0.04 - ложь
Почему только через запятую когда везде точка стоит. у меня win7 QT, а дебажу я пока на VS. Щас в кутэ попробую
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
21.06.2011, 16:14     Глюк при заполнении массива #18
grizlik78, виноват, не туда смотрел. Исправилась только ошибка при сравнении:

Глюк при заполнении массива
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
21.06.2011, 16:37     Глюк при заполнении массива #19
Цитата Сообщение от Петр91 Посмотреть сообщение
row[1]==0,02 - истина
Это не истина, это 2 (которую можно рассматривать как истину)
Почитайте про оператор "запятая"
Ну и посмотрите, например, что выведет эта строчка:
C++
1
cout << (1,2,3,4,5) << endl;
Добавлено через 17 минут
Цитата Сообщение от Петр91 Посмотреть сообщение
Заменил float на double вывел массив, все ок! Даже сравнивает правильно целые числа! ноль, один, пять. А вот с дробными проблема!
Просто проблема спряталась, а вовсе не решилась. В любом учебнике должно быть сказано, что сравнивать оператором == два вещественных числа неправильно. Нормальные компиляторы даже предупреждения в этом месте выводят. Если кто-то использует по необходимости ==, то он должен чётко представлять, что он делает.
А два числа, как правило, можно сравнить по условию, что разность между ними по абсолютной величине не превышает некоторой допустимой погрешности. То есть
C
1
fabs(x1-x2) < 1e-6;
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.06.2011, 16:56     Глюк при заполнении массива
Еще ссылки по теме:

Ошибка при заполнении массива C++
При заполнении двумерного массива выдает ошибку C++
Ошибка при заполнении динамического массива C++

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

Или воспользуйтесь поиском по форуму:
Петр91
4 / 4 / 1
Регистрация: 17.05.2010
Сообщений: 108
21.06.2011, 16:56  [ТС]     Глюк при заполнении массива #20
Спасибо большое!
Yandex
Объявления
21.06.2011, 16:56     Глюк при заполнении массива
Ответ Создать тему
Опции темы

Текущее время: 03:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru