2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Не могу исправить ошибку.
Сообщение29.12.2011, 19:36 


09/12/11
9
Помогите найти ошибку в програме: нужно сравнить z1 и z2, но почему-то результат постоянно разный.При том обе формулы правильны.Может я неправильно их сравниваю?

#include "stdafx.h"
#include "iostream"
#include "cmath"
using namespace std;
int main()
{ setlocale(0,"russian");
double a, z1, z2, v;
cout<<"Введите число";
cin>>a;
z1=(sqrt(a+2))/(sqrt(2*a))-(a)/sqrt(2*a*2)+2/a-sqrt(2*a)*sqrt(a)-sqrt(2.0)/(a+2);
z2=1/(sqrt(a)+sqrt(2.0));
v=z1-z2; // V - переменная для сравнения;
if(v=0){
cout<<"z1 равен z2";}
else{
cout<<"z1 не равен z2";}
system("pause");
return 0;
}

 Профиль  
                  
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 19:50 
Заслуженный участник


27/04/09
28128
Что видно сразу — вы спутали == с =. И код нечиатемый. Для читаемости можно положить его внутрь тегов [code]...[/code], добавить отступы и прочую красоту.

 Профиль  
                  
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 20:03 
Заслуженный участник


09/08/09
3438
С.Петербург
AlexanderGrey в сообщении #521390 писал(а):
Может я неправильно их сравниваю?
Неправильно сравниваете.
1. Как абсолютно справедливо заметил arseniiv, операция сравнения '==', а не '='.
2. Два действительных числа, полученных в результате разных вычислений, практически никогда не совпадут точно; их всегда надо сравнивать с некоторой допустимой погрешностью.

Если есть сомнения в правильности программы, вставьте вывод z1 и z2 и проверьте на калькуляторе.

Ну а код лучше "положить" не внутрь тегов code, а внуть тегов syntax: Как подсвечивать синтаксис?

 Профиль  
                  
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 20:30 
Заслуженный участник


27/04/09
28128

(Оффтоп)

Ой, да, код-то точно. Забыл.

 Профиль  
                  
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 21:19 


09/12/11
9
А проверить формулы по отдельности не додумался)Но когда проверил результат был разный, очевидно, что я действительно допустил ошибку в написании формул.

 Профиль  
                  
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 21:52 
Аватара пользователя


31/10/08
1244
AlexanderGrey
дело в том что числа в компьютере имеют ограниченное число разрядов. Поэтому не возможно точно представить действительные числа.
Тут можно прочитать. Правда статья пафосная.
http://www.delphikingdom.com/asp/viewit ... alogid=374

Второе это то что после каждой операции происходит округление чисел. Поэтому точность теряется.
А да проблема от перестановки слагаемых сумма меняется. Сразу успокою в большинстве случаев не критично.
Можете заглянуть сюда и убедится. Да нужна регистрация.
http://www.intuit.ru/department/superco ... seraspp/2/
примерно на 54 минуте можно посмотреть как виду числа с плавающей точкой при сложение в разном порядке(задача про крокодила).

Третье есть разные форматы чисел с плавающей точкой single, double, long double( extended в паскале)
С++
Код:
double v;
v=0.1;
if(v==0.1){
cout<<"равен";}
else{
cout<<"не равно";}

При такой записи не исключен случай не равенства ввиду того что 0.1 точно не представим.
А во вторых в записи v==0.1 число 0.1 скорее всего будет иметь тип long double, а v тип double Это значит что числа v компьютер преобразует к long double путём замены недостающих разрядов нулями. Поэтому такое сравнение не сработает.

Четвёртое sin, sqrt, power, exp итд. обычно на CPU вычисляются с точностью double. Умножение и сложение умеют большую точность. Но они могут быть вычислены и с меньшей точностью. Что используется для ускорения при оптимизации. До недавнего времени на GPU sin и cos к примеру считаются с точностью single сейчас вроде как наметился переход к double.

Поэтому сравнение надо делать с некоторым допуском.

Пример таких сравнений на Borland pascal.
Код:
{ Проверяет два числа на равенство с точностью до Eps }
Function Eq(Const a,b : Real) : Boolean;
Begin
  Eq:=Abs(a-b)<=Eps;
End;

{ Проверяет два числа на неравенство с точностью до Eps }
Function Ne(Const a,b : Real) : Boolean;
Begin
  Ne:=Abs(a-b)>Eps;
End;

{ Проверяет два числа на "меньше или равно" с точностью до Eps }
Function Le(Const a,b : Real) : Boolean;
Begin
  Le:=(a<=b) Or Eq(a,b);
End;

А да в своё время взял отсюда
http://antosha.com/onzi/modules/geometry.zip

 Профиль  
                  
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 22:10 


09/12/11
9
Спасибо за информацию.Я лишь начинающий програмист в экономической кибернетике, так что почти любая информация для меня полезна)

 Профиль  
                  
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 23:18 


09/12/11
9
а http://antosha.com/onzi/modules/geometry.zip к сожалению не открывается сайт.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group