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

Можно ли использовать не целые числа в For? - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Rand, которая генерирует как целые, так и дробные числа http://www.cyberforum.ru/cpp-beginners/thread1144157.html
Доброго времени суток, форумчане. подскажите, пожалуйста, как нужно прописать функцию rand(), чтобы я получил и целые, и дробные элементы. Например, у меня одномерный массив из 10 элементов. Нужно его рандомно заполнить значениями от -5 до 5, включая дробные (с точностью до 0,1). То есть, фактически от -5.0 до 5.0. Как сделать интервал я разобрался, как заполнить массив целыми числами - тоже, как...
C++ Описать структуру с именем TOVAR Помогите пожалуста!! 1 . Описать структуру с именем TOVAR , которая содержит следующие поля: - Name - название товара ; - Cost_Z - цена закупки товара ; - Cost_P - цена продукции. - Quantity - количество единиц товара ; - Pributok - прибыль. 2 . Написать программу, использующую данную структуру и выполняет следующие действия : - Вводит с клавиатуры массив данных SHOP , состоящий из N... http://www.cyberforum.ru/cpp-beginners/thread1144147.html
Написать строку задом наперед C++
помогите пожалуйста отладить, задача написать строку задом наперед. Работает не правильно, что я не так сделал? Вот мой код: void swap(char c) { int i,j; for (i=0; c !='\0'; i++); for (j=0,i--; i>j; i--,j++) { char s; s=c; c=c; c=s; } }
C++ Траектория снаряда
не знаю правильно сделал программу формули: a= \frac{\pi }{3} , x={V}_{0}tcosa , y={V}_{0}tsina-g\frac{{t}^{2}}{2} , V=35 , пушки кут = а по цифрам вроде правильно кто знает физику подскажите все правильно (точность 2 километра) #include <iostream> #include <conio.h> using namespace std;
C++ Как производится удаление строк матрицы? http://www.cyberforum.ru/cpp-beginners/thread1144131.html
Дан массив и матрица.Из матрицы М удалить строки, сумма элементов которых больше суммы элементов массива V. строки и суммы элементов нашла.. а как удалять их - незнаю.. :-| будет ли правильным задать новую матрицу и в нее эти строки с элементами назначать или как то по другому?мне просто в дальнейшем предстоит работать с уже преобразованной матрицей.. а как к ней дойти, добиться ее - не...
C++ Как правильно описать тип данных Парни, переделываю программу на Delphi в С++. Столкнулся с проблеммой. Не знаю, как в С++ описыватся такой тип данных. type pat=array of integer; ver1=array of integer; ver2=array of integer; end; var Form1: TForm1; ver:ver1; подробнее

Показать сообщение отдельно
BlackSpace
136 / 129 / 51
Регистрация: 15.03.2014
Сообщений: 274
10.04.2014, 14:25     Можно ли использовать не целые числа в For?
JaguarT51, необходимо понимать, что дробные числа представляются с ограниченной точностью в памяти.
Не рекомендую сравнивать напрямую два вещественных числа, так как можно получить неожиданные результаты.
Постараюсь пояснить на примерах.

Пример 1. Тут, вполне возможно, все будет работать как и ожидалось.
C++
1
2
3
4
5
...
    double x;
    for ( x = 0.2; x < 0.6; x += 0.1 )
        cout << x << endl;
...
Вывод программы
Кликните здесь для просмотра всего текста
0.2
0.3
0.4
0.5


Пример 2. Однако, в следующем пример вывод программы может быть несколько не такой какой хотелось бы.
C++
1
2
3
4
5
...
double x;
    for ( x = 0.299; x < 0.3; x += 0.0001 )
        cout << x << endl;
...
Вывод программы
Кликните здесь для просмотра всего текста
0.299
0.2991
0.2992
0.2993
0.2994
0.2995
0.2996
0.2997
0.2998
0.2999 // должно быть последним в выводе
0.3 // откуда ? : )

Дело в том, что последнее в выводе значение 0.3 округленное.

Можно сделать вывод с повышенной точностью.
C++
1
2
3
4
5
6
7
8
...
#include <iomanip>
...
double x;
    cout << fixed << setprecision( 16 );
    for ( x = 0.299; x < 0.3; x += 0.0001 )
        cout << x << endl;
...
Тогда вывод будет
Кликните здесь для просмотра всего текста
0.2990000000000000
0.2991000000000000
0.2992000000000000
0.2993000000000000
0.2993999999999999
0.2994999999999999
0.2995999999999999
0.2996999999999999
0.2997999999999999
0.2998999999999999 // должно быть последним в выводе
0.2999999999999999 // этого тут не должно было быть, но оно меньше чем 0.3 и оно тут есть


В некоторых местах данного вывода хорошо видно что вещественные числа хранятся с ограниченной точностью.

Один из путей решения.
Подсчитать заранее количество необходимых шагов и использовать целочисленное сравнение
в цикле.

Пример 3. Приведу программу полностью.
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
26
27
28
#include <iostream>
#include <cmath>
#include <iomanip>
 
using namespace std;
 
int main() {
 
    // считаем, что мы уверены, что a, b и h положительные
    // а также, что b > a и h <= b - a
    double a = 5.5551; // нижняя граница
    double b = 5.5552; // верхняя граница
    double h = 0.00001; // шаг вычислений
 
    // считаем количество шагов
    int count = fabs( floor( ( ( b - a ) /  h ) + 0.5 ) ); // важно верно посчитать количество шагов
    // fabs( floor( ( ( b - a ) /  h ) + 0.5 ) ) + 1; // + 1 если включаем в расчет верхнюю границу ( 5.5552 в нашем случае )
 
    cout << "Количество шагов = " << count << endl;
 
    cout << fixed << setprecision( 16 );
    for ( int i = 0; i < count; ++i ) { // тут уже целочисленное сравнение
        double x = a + h * i;
        cout << x << endl; // и вывод, который ожидаем
    }
 
    return 0;
}
Вывод программы
Кликните здесь для просмотра всего текста
Количество шагов = 10
5.5551000000000004
5.5551100000000000
5.5551200000000005
5.5551300000000001
5.5551400000000006
5.5551500000000003
5.5551600000000008
5.5551700000000004
5.5551800000000000
5.5551900000000005


Существует и другой путь.
Сравнивать два вещественных числа с определенной точностью.

Пример 4.
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 <iomanip>
 
using namespace std;
 
int main() {
 
    // считаем, что мы уверены, что a, b и h положительные
    // а также, что b > a и h <= b - a
    double a = 0.0003;//5.55551; // нижняя граница
    double b = 0.0004;//5.55552; // верхняя граница
    double h = 0.000001; // шаг вычислений
    double eps = 0.0000001; // точность вычисления должна быть на порядок выше чем шаг вычислений
 
    cout << fixed << setprecision( 16 );
 
    for ( double x = a; ( b - x ) > eps; x += h ) // сравниваем с определнной точностью
        cout << x << endl;
 
    return 0;
}
Вывод программы как и ожидалось.
Кликните здесь для просмотра всего текста
...
0.0003940000000000
0.0003950000000000
0.0003960000000000
0.0003970000000000
0.0003980000000000
0.0003990000000000


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