2014 dxdy logo

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

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




 
 Не могу исправить ошибку.
Сообщение29.12.2011, 19:36 
Помогите найти ошибку в програме: нужно сравнить 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 
Что видно сразу — вы спутали == с =. И код нечиатемый. Для читаемости можно положить его внутрь тегов [code]...[/code], добавить отступы и прочую красоту.

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

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

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

 
 
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 20:30 

(Оффтоп)

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

 
 
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 21:19 
А проверить формулы по отдельности не додумался)Но когда проверил результат был разный, очевидно, что я действительно допустил ошибку в написании формул.

 
 
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 21:52 
Аватара пользователя
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 
Спасибо за информацию.Я лишь начинающий програмист в экономической кибернетике, так что почти любая информация для меня полезна)

 
 
 
 Re: Не могу исправить ошибку.
Сообщение29.12.2011, 23:18 
а http://antosha.com/onzi/modules/geometry.zip к сожалению не открывается сайт.

 
 
 [ Сообщений: 8 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group