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

double и for - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.82
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 16:42     double и for #1
Здравствуйте, объясните пожалуйста почему в операции:
C++
1
for (double y = .1; y != 1.0; y += .1)
получается бесконечный цикл, то есть проскакивает выражение 1.0 == 1.0 - как true

ps я знаю что не корректно использоваться не целочисленный "счетчик", но терзает любопытство почему...
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
28.07.2011, 16:44     double и for #2
List2006, Архитектура. Где-то на форуме обсуждалось.
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 16:50  [ТС]     double и for #3
Цитата Сообщение от ForEveR Посмотреть сообщение
...Где-то...
уж лучше бы ты меня в гугль отправил , а по конкретнее можно где именно это было?
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
28.07.2011, 16:55     double и for #4
Из-за неточности вещественных чисел.
Для примера - посмотрите результат 10./3*3.
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 16:59  [ТС]     double и for #5
Цитата Сообщение от diagon Посмотреть сообщение
Из-за неточности вещественных чисел.
Для примера - посмотрите результат 10./3*3.
я это понимаю, но в данном случае же не использовалось деление,
а нули позади числа не имеет значения (как гласит нам математика):
1.0 тоже что и 1.000000000000000000

тут можно сделать вывод что С++ заведома делает число не правильным, дописывая скажем
в 1.0 - 1.00000000000000000001 ?
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
28.07.2011, 17:06     double и for #6
Можно погуглить.
Ну или скомпилить этот код
C++
1
2
3
4
5
6
7
#include <iostream>
#include <iomanip>
int main(){
    double y = 0.1;
    for (; y < 1.0; y += .1);
    std::cout << std::fixed << std::setprecision(16) << y - 1.1;
}
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
28.07.2011, 17:09     double и for #7
Потому как 0.1 в двоичной системе счисления - это бесконечная периодическая дробь.
Естественно, при представлении в машине она отсекается-округляется...
Таким образом 10*0.1 != 1.0 для дробных чисел
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 17:47  [ТС]     double и for #8
если удлинить выдачу разрядов
std::setprecision(80)

то видно что после 16 добавляются какие то шумы и добавляются они тоже ограниченно (то есть потом идут "нечто" - нули) и для одного и того же значения, скажем "y = .1" - шумы будут постоянны.
Но, если после запятой значение "0", скажем "1.0" то шумы не добавляются.

Отсюда вывод: получается что С++ заведомо добавляет эти шумы чтобы достичь свойств вещественных чисел (то есть это по-моему не прихоть железа, а прихоть потребности сделать не точно).

PS либо шумы это глюк объекта cout.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
28.07.2011, 17:50     double и for #9
Цитата Сообщение от List2006 Посмотреть сообщение
если удлинить выдачу разрядов
std::setprecision(80)
Где же Вы столько разрядов в double возьмете? Оо
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 17:55  [ТС]     double и for #10
даже при деление "1.0/10.0" - шумы точно такие же как, как если бы была просто константа "0.1".
Напомню что для 1.0 и 10.0 шумов нет.

Добавлено через 1 минуту
Цитата Сообщение от fasked Посмотреть сообщение
Где же Вы столько разрядов в double возьмете? Оо
их нет, но видимо для вычислений они прикручиваются, или опять же говорю глюк cout.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
28.07.2011, 18:05     double и for #11
List2006, какие шумы?!!!!
Фокус в том, что для ВСЕХ дробных чисел, кроме степеней двойки (которые представляются ТОЧНО) при переводе в двоичную систему получите бесконечную дробь. Это математика, а не "шумы"...
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 18:19  [ТС]     double и for #12
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
List2006, какие шумы?!!!!
Фокус в том, что для ВСЕХ дробных чисел, кроме степеней двойки (которые представляются ТОЧНО) при переводе в двоичную систему получите бесконечную дробь. Это математика, а не "шумы"...
Какая блин математика, ты код скомпилируй как я тебе говорил с 80 разрядами.
Вот результаты для констант (и где там твоя теория с двойкой??):
0.1 = 0.10000000000000000555111512312578270211815834045410156250000000000000000000000000
0.2 = 0.20000000000000001110223024625156540423631668090820312500000000000000000000000000
0.3 = 0.29999999999999998889776975374843459576368331909179687500000000000000000000000000
0.1 = 0.10000000000000000555111512312578270211815834045410156250000000000000000000000000

0.1 / 2.0 = 0.05000000000000000277555756156289135105907917022705078125000000000000000000000000

сам код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cmath>
 
using namespace std;
 
int main (int argc, char** argv)
{
        std::cout << std::fixed << std::setprecision(80) 
        << "\n0.1 = " << 0.1
        << "\n0.2 = " << 0.2
        << "\n0.3 = " << 0.3
        << "\n0.1 = " << 0.1
        << "\n0.1 / 2.0 = " << 0.1 / 2.0;
 
    std::cin.get();
    return 0;
}
ps оформление, подключенные библиотеки - это у меня для тестов, я просто скопировал все.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
28.07.2011, 18:26     double и for #13
List2006, шумы в голове у Вас, реальных разрядов здесь около 15-16, все остальное мусор, который не относится к числу.

Не по теме:

Надо же так додуматься, и смех и грех

List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 18:28  [ТС]     double и for #14
это не завесит от памяти, времени, эти шумы постоянны для значений за нулём.
К сожалению не могу попробовать на другом компиляторе (у меня MinGW).

PS какая математика, когда представление в памяти идет не в математических дробях, а банально в битах, где после 16 бит нечего нет. Я не думаю чтобы представить константу компилятор заставляет вычислить её (ему придется каждый раз подбирать для этого значение дроби).

Добавлено через 1 минуту
Цитата Сообщение от fasked Посмотреть сообщение
List2006, шумы в голове у Вас, реальных разрядов здесь около 15-16, все остальное мусор, который не относится к числу.

Не по теме:

Надо же так додуматься, и смех и грех

да я уже и без вас это сказал, факт что числа для константы и для выражении постоянны, не зависят от времени, памяти, и расположение памяти.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
28.07.2011, 18:31     double и for #15
Цитата Сообщение от List2006 Посмотреть сообщение
Я не думаю чтобы представить константу компилятор заставляет вычислить её (ему придется каждый раз подбирать для этого значение дроби).
А как еще-то? Просто вычислить придеться всего один раз. А уж при выводе точно каждый раз пересчет идет.
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
28.07.2011, 18:40     double и for #16
List2006, не шуми, это не шумы (хе-хе, каламбурчик).

Цитата Сообщение от List2006 Посмотреть сообщение
PS какая математика, когда представление в памяти идет не в математических дробях, а банально в битах, где после 16 бит нечего нет.
Как после 16 бит ничего нет? Куда делось?
Числа в памяти действительно представлены битами. И в случае константы типа double это будет 64 бита.
Цитата Сообщение от List2006 Посмотреть сообщение
Я не думаю чтобы представить константу компилятор заставляет вычислить её (ему придется каждый раз подбирать для этого значение дроби).
Кто кого заставляет? Компилятор просто вычисляет битовое представление константы и сохраняет его в памяти, если не может сразу использовать в вычислениях.

Цитата Сообщение от List2006 Посмотреть сообщение
даже при деление "1.0/10.0" - шумы точно такие же как, как если бы была просто константа "0.1".
Напомню что для 1.0 и 10.0 шумов нет.
И что тут странного?
Двоичное представление десятичного числа 1 это 1 (речь об абстрактном, а не машинном представлении)
Двоичное представление десятичного числа 10 это 1010
Двоичное представление десятичного числа 0.1 это 0.0(0011), где в скобках периодически повторяемая часть числа.
Первые два числа можно точно представить конечным числом битов, третье в явном виде не получится. Отброшенная часть и даёт те самые "шумы"
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
28.07.2011, 18:46     double и for #17
Короче, пиши
C++
1
for (double y = .1; y < 1.0; y += .1)
и не парься...
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
28.07.2011, 18:49     double и for #18
Я бы использовал что-нибудь вроде
C++
1
2
3
4
for (int i = 1; i < 10; ++i)
{
    double y = i*(1.0/10);
}
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
28.07.2011, 18:50     double и for #19
Цитата Сообщение от grizlik78 Посмотреть сообщение
double y = i*(1.0/10);
double y = i * 0.1;//
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.07.2011, 18:51     double и for
Еще ссылки по теме:

Почему перестает работать программа при замене double на long double? C++
Преобразовать 2 числа int в 1 число float(double) | double int1.int2 C++
Почему мы пишем double x (double y)? а не через запятую double x,y C++

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

Или воспользуйтесь поиском по форуму:
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
28.07.2011, 18:51     double и for #20
Deviaphan, ну да, но у меня 10 можно заменить какой-нибудь другой константой
Yandex
Объявления
28.07.2011, 18:51     double и for
Ответ Создать тему
Опции темы

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