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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.82
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
#1

double и for - C++

28.07.2011, 16:42. Просмотров 1490. Ответов 30
Метки нет (Все метки)

Здравствуйте, объясните пожалуйста почему в операции:
C++
1
for (double y = .1; y != 1.0; y += .1)
получается бесконечный цикл, то есть проскакивает выражение 1.0 == 1.0 - как true

ps я знаю что не корректно использоваться не целочисленный "счетчик", но терзает любопытство почему...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.07.2011, 16:42
Здравствуйте! Я подобрал для вас темы с ответами на вопрос double и for (C++):

Ошибки error C2296: -: недопустимо, левый операнд имеет тип "double (__cdecl *)(double,double,double - C++
Думаю из-за polp #include<iostream> #include<cmath> #include<cstdlib> using namespace std; double polp(double af,double...

Ошибка: error LNK2001: unresolved external symbol "double __cdecl Akk(double,double,double)" - C++
#include <iostream> #include <cmath> using namespace std; double Akk(double x, double y, double z); int main() { int a, b, c; ...

Почему мы пишем double x (double y)? а не через запятую double x,y - C++
почему мы пишем double x (double y)? а не через запятую double x,y

Исправить ошибки "cannot convert 'double (*)(double)' to 'double'" и "too many arguments to function" - C++
пожалуйста проверьте и помогите исправить ошибки: #include<iostream> #include<stdio.h> #include<math.h> #include<stdlib.h> ...

Почему перестает работать программа при замене double на long double? - C++
Здравствуйте! Прошу помощи чтобы разобраться в следующем вопросе: Нашел программу в интернете, запустил - все работает, но когда решил...

Преобразовать 2 числа int в 1 число float(double) | double int1.int2 - C++
Всем привет. Изучая азы C++, столкнулся с такой проблемой. Есть два значения типа int, их необходимо преобразовать в одно значение типа...

30
grizlik78
Эксперт С++
1956 / 1449 / 115
Регистрация: 29.05.2011
Сообщений: 3,008
28.07.2011, 18:40 #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), где в скобках периодически повторяемая часть числа.
Первые два числа можно точно представить конечным числом битов, третье в явном виде не получится. Отброшенная часть и даёт те самые "шумы"
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
28.07.2011, 18:46 #17
Короче, пиши
C++
1
for (double y = .1; y < 1.0; y += .1)
и не парься...
0
grizlik78
Эксперт С++
1956 / 1449 / 115
Регистрация: 29.05.2011
Сообщений: 3,008
28.07.2011, 18:49 #18
Я бы использовал что-нибудь вроде
C++
1
2
3
4
for (int i = 1; i < 10; ++i)
{
    double y = i*(1.0/10);
}
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
28.07.2011, 18:50 #19
Цитата Сообщение от grizlik78 Посмотреть сообщение
double y = i*(1.0/10);
double y = i * 0.1;//
0
grizlik78
Эксперт С++
1956 / 1449 / 115
Регистрация: 29.05.2011
Сообщений: 3,008
28.07.2011, 18:51 #20
Deviaphan, ну да, но у меня 10 можно заменить какой-нибудь другой константой
0
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 19:32  [ТС] #21
а как можно получить кусок памяти в двоичной системе?
то есть хочу получить значение float i = 0.1; как оно лежит прям в памяти.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
28.07.2011, 19:33 #22
Изъяснись точнее.
0
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 19:36  [ТС] #23
а лучше покажите на примере как перевести 0.1 в представление float
то есть с мантиссами и прочими
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
28.07.2011, 19:37 #24
float i = 0.1f;
0
List2006
24 / 16 / 2
Регистрация: 19.12.2009
Сообщений: 366
28.07.2011, 19:39  [ТС] #25
Цитата Сообщение от Deviaphan Посмотреть сообщение
Изъяснись точнее.
-хочу наглядно увидеть как С++ хранить число 0.1
-и попробовать самому перевести в число, чтобы наглядно понять как оно переходит в то число:
0.100000000000000005551115123125782702118158340454101562500000000000000000000000
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
28.07.2011, 19:43 #26
Побитное представление
31 - бит знака
30-23 - порядок
22-0 - мантисса

За подробностями в гугл.

Добавлено через 1 минуту
Битовое представление можешь формировать в unsigned int, а потом присвоить float'y

C++
1
2
unsigned int v1 = ...;
float f = *((float*)&v1);
0
grizlik78
Эксперт С++
1956 / 1449 / 115
Регистрация: 29.05.2011
Сообщений: 3,008
28.07.2011, 19:49 #27
Цитата Сообщение от List2006 Посмотреть сообщение
а как можно получить кусок памяти в двоичной системе?
В виде байтов можно посмотреть.
Преобразованием указателя, например. Ну, это уже показали.
Или с помощью объединения
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
union float_bytes{
    float f;
    unsigned char b[sizeof(float)];
};
 
int main()
{
    float_bytes v;
    v.f = 0.1;
    for (unsigned i = 0; i < sizeof(float); ++i)
        std::cout << "0x" << std::hex << (unsigned)v.b[i] << std::endl;
    return 0;
}
Добавлено через 4 минуты
Что касается числа 0.1 то это есть прямо в английской википедии. Русскую не смотрел.
1
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
28.07.2011, 20:51 #28
Цитата Сообщение от List2006 Посмотреть сообщение
а лучше покажите на примере как перевести 0.1 в представление float
то есть с мантиссами и прочими
Читать стандарт IEEE-754. В сети - дофига материалов.
Перевод дробных - умножением на основание системы счисления. В сети дофига материалов на эту тему.
0
easybudda
Модератор
Эксперт CЭксперт С++
9663 / 5613 / 952
Регистрация: 25.07.2009
Сообщений: 10,777
28.07.2011, 21:22 #29
Цитата Сообщение от grizlik78 Посмотреть сообщение
Или с помощью объединения
Поздно я это заметил, сначала почти так же по-своему написал
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <limits.h>
 
#define LLBITS (CHAR_BIT * sizeof(long long))
 
typedef union {
    double dval;
    unsigned long long ival;
} un_t;
 
int main(void){
    un_t un;
    int i;
    
    if ( sizeof(double) != sizeof(long long) ){
        printf("Shit happens!\n");
        return 1;
    }
    
    while ( ( i = LLBITS ) && printf("\nDouble value: ") && scanf("%lf", &un.dval) == 1 )
        while ( i )
            printf("%d", ( un.ival >> --i ) & 1);
    
    return 0;
}
1
rangerx
1933 / 1542 / 141
Регистрация: 31.05.2009
Сообщений: 2,913
28.07.2011, 23:52 #30
Цитата Сообщение от List2006 Посмотреть сообщение
и попробовать самому перевести в число
1) 0.1 * 2 = 0.2
2) 0.2 * 2 = 0.4
3) 0.4 * 2 = 0.8
4) 0.8 * 2 = 1.6
5) 0.6 * 2 = 1.2
6) 0.2 * 2 = 0.4 // зациклились, повторяется п. 2, получилась периодическая дробь

0.1d = 0.0(0011)b

Т.е. умножаешь на 2 пока не наберётся необходимое количество разрядов либо не получится 0 в мантиссе, например:
1) 0.5 * 2 = 1.0
0.5d = 0.1b
2
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.07.2011, 23:52
Привет! Вот еще темы с ответами:

Какая-нибудь реализация функции void Fun (double in, double *out) - C++
Подскажите, пожалуйста, какую-нибудь любую реализацию прототипа функции: void Fun (double in, double *out)

long double и double в MSVC 12 одно и тоже, нужна информация,желательно быстрей - C++
Здравствуйте все знают что в VC long double и double одно и тоже, да и при простой проверке это легко выясняется, но нужна информация от...

std::copy из vector<double> в *double, непонятный warning - C++
double myD={10,20,30,40,50,60,70}; std::vector&lt;double&gt; myvector (7); std::copy ( myD, myD+7, myvector.begin() ); std::copy (...

invalid operands of types ‘double*’ and ‘double’ to binary ‘operator*’ - C++
#include &quot;mpi.h&quot; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;math.h&gt; #define count 120 int main(int argc,char *argv) { ...


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

Или воспользуйтесь поиском по форуму:
30
Yandex
Объявления
28.07.2011, 23:52
Ответ Создать тему
Опции темы

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