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

Возникновение странных погрешностей около нуля и возникающие из-за нее косяки - C++

Восстановить пароль Регистрация
 
Woody-krsk
1 / 1 / 0
Регистрация: 20.12.2010
Сообщений: 62
05.12.2011, 11:51     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки #1
Всем привет!
Сразу к делу, тренирую свое генетический алгоритм на тестовых функциях. Одна из них - функция де Йонга, формула во вложениях. Казалось бы, все просто, но когда начал прогонять на алгоритме, понял, что где то собака порылась, начал искать, сделал небольшой код для этого
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#define _USE_MATH_DEFINES
#include <math.h>
using namespace std;
 
double func_de_jong (double, double);
 
int main(){
    setlocale(0,"");
    ofstream(out);
    out.open("01.txt");
    cout << "Start";
    for (int i = 0; i < 1000; i++){
        cout << ".";
        for (int j = 0; j < 1000; j++){
            double point1 = -5 + (double)i * .01;
            double point2 = -5 + (double)j * .01;
            out << "" << point1 << " " << point2 << " " << func_de_jong(point1,point2) << endl;
        }
    }
    out.close();
    cout << "Done!" << endl;
    double x = -1, y = 1.05;
    double a = 100 * (pow(x,2) - y);
    cout << "a = "<< a << endl;
    double b = pow((1 - x), 2);
    cout << "b = "<< b << endl;
    double c = a + b +1;
    cout << "c = "<< c << endl;
    double d = -100/c;
    cout << "d = "<< d << endl;
    double f = d + 100;
    cout << "f = "<< f << endl;
    getch();
    return 0;
}
double func_de_jong (double x, double y){
    double result = 0;
    result = (-100 / (100 * (pow((double)x,2) - y) + pow((double)(1 - x),2) + 1)) + 100;
    return result;
}
И вот обнаружил я следующий косяк, который и раньше всплывал, но я обошел его, как мне показалось, сменой типа переменной с float на double. А косяк следующий, при приближении результата вычислений к нулю, начинает вылезать какая то неведомая погрешность, числа превращаются вместо, например, 0,0001 в 0,0000999999996 и все идет наперекосяк. Например, эта функция при подсчетет руками не существует в точке (-1;1,05), т.к. в знаменателе получается 0, но программа выдает результат 2.2518e+016 ! Причем, что самое смешное, мне даже excel выдал такой же результат! Ко всему этому, в этой же точке, при выполнении вычислиней из цикла с записью в файл программа стабильно выдает результат -5,63E+15, т.е. ошибка получается 10^32! Честно говоря я вообще в шоке и не понимаю, что делать и как быть, и я ли дурак или это лыжи не едут.
Изображения
 
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.12.2011, 11:51     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки
Посмотрите здесь:

Определить периметр правильного n-угольника, описанного около окружности радиуса r C++
Начинающему с нуля C++
C++ С ++ с нуля
C++ Программа тестирования, не могу разобрать свои косяки :(.
C++ Косяки с графикой при переключении окон
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
05.12.2011, 12:28     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки #2
Цитата Сообщение от Woody-krsk Посмотреть сообщение
начинает вылезать какая то неведомая погрешность, числа превращаются вместо, например, 0,0001 в 0,0000999999996
Всё нормально, не пугайся. Вещественные числа почти всегда представлены с некоторой погрешностью. Поэтому сравнивать вещественные числа на "равно" практически бесполезно...

Не используй pow для возведения в квадрат. х*х будет и эффективнее и погрешность может меньше даже быть.
Woody-krsk
1 / 1 / 0
Регистрация: 20.12.2010
Сообщений: 62
05.12.2011, 13:27  [ТС]     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки #3
Пробовал, результат тот же. И что теперь делать то? Как мне эту функцию закодить? И главное, в чем причина разных результатов в консоли и в файле для той точки?
Байт
 Аватар для Байт
13974 / 8805 / 1227
Регистрация: 24.12.2010
Сообщений: 15,949
05.12.2011, 13:43     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки #4
http://gmplib.org/
Woody-krsk
1 / 1 / 0
Регистрация: 20.12.2010
Сообщений: 62
06.12.2011, 06:58  [ТС]     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки #5
А менее громоздких решений нет?

Добавлено через 7 минут
Громоздких в том плане, что не городить еще одну специальную библиотеку, а так сказать в стандартной комплектации VC?

Добавлено через 13 часов 42 минуты
Расскажите как библиотеку эту прикрутить, а то гугляма не помогает, документашка внутри тоже как-то молчит об этом.
Байт
 Аватар для Байт
13974 / 8805 / 1227
Регистрация: 24.12.2010
Сообщений: 15,949
06.12.2011, 12:05     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки #6
Я бы просто взял исходники, заточил бы под себя и - вперед.
Хлопот конечно много, но зато будешь владеть мощным инструментом, и все грабли машинной арифметики тебе по фигу.
Так как меня тоже интересует длинная арифметика (есть даже кой-какие наработки, но с только с целыми) я скачал gmp-5.0.2.tar.lz
Однако winRar его не берет. Очевидно, что это линуховский архив. Вот будет время, загружу Knoppix, разархивирую, об успехах сообщу.
Woody-krsk
1 / 1 / 0
Регистрация: 20.12.2010
Сообщений: 62
06.12.2011, 18:20  [ТС]     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки #7
Хм... У меня разархивировалось то все нормально, куда дальше приляпывать не пойму. Передеалть под себя не вариант, уровень мягко говоря не тот.
Байт
 Аватар для Байт
13974 / 8805 / 1227
Регистрация: 24.12.2010
Сообщений: 15,949
06.12.2011, 19:40     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки #8
Цитата Сообщение от Woody-krsk Посмотреть сообщение
Хм... У меня разархивировалось то все нормально, куда дальше приляпывать не пойму. Передеалть под себя не вариант, уровень мягко говоря не тот.
Ты не мог заархивировать все обратно, каким-нибудь zip или rar и выложить это сюды, чтоб я мог это взять WinRar-ом. Если там есть исходники, попробую разобраться.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.12.2011, 11:23     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки
Еще ссылки по теме:

C++ вообще с нуля
C++ База будет хранить примерно около 5 таблиц по 1000 элементов. Что выбрать?
Класс для выполнения арифметических операций над числами с учётом абсолютной и относительной погрешностей C++

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

Или воспользуйтесь поиском по форуму:
Байт
 Аватар для Байт
13974 / 8805 / 1227
Регистрация: 24.12.2010
Сообщений: 15,949
09.12.2011, 11:23     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки #9
Woody-krsk, IDE это чего такое? среда Visual Studio 2008
Вот и есть IDE (Integrated Development Environment) - Интегрированная среда разработки.
Yandex
Объявления
09.12.2011, 11:23     Возникновение странных погрешностей около нуля и возникающие из-за нее косяки
Ответ Создать тему
Опции темы

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