konto usunięte

Temat: Problem z liczeniem małych liczb

Hej!

Piszę na zajęcia taki prosty programik.
Ma on wyznaczyć współczynnik opóźnienia względnego zegara poruszającego się z jakąś tam prędkością.


#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <math.h>

#define PI 3.14159265

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
// Deklarujemy predkosc swiatla
int c = 299792458;
double lambda;
ofstream plik("lambda.txt");
for(int v=0;v<=c/2;v=v+10000)
{
double argument = 1-(v^2)/(c^2);
lambda = 1 /(sqrt(argument));
plik << argument << "\t" << v << "\t" << lambda << endl;
}
plik.close();

return 0;
}


Z nie wyjaśnionych przyczyn wychodzą same jedynki...
Tomasz G.

Tomasz G. programista,
konstruktor
elektronik

Temat: Problem z liczeniem małych liczb

"^" to XOR w C, użyj pow(v,2) lub lepiej po prostu (v*v)

http://pl.wikibooks.org/wiki/C/Operatory

konto usunięte

Temat: Problem z liczeniem małych liczb

W tym wyrażeniu:

double argument = 1-(v^2)/(c^2);

po prawej stronie masz same int-y.
Najprościej dla kompilatora (i najszybciej) jest zatem policzyć to wszystko jako int a potem skonwertować na double.
Czy tak kompilator robi w twoim przypadku? Może niekoniecznie, ale na wszelki wypadek lepiej by wyglądało (także dla ludzi którzy będą to potem wspierać) jako (zakładam że chodzi o C++):


template < class T >
T fsqr(const T &arg)
{
return arg * arg;
}

double argument = 1.0 -
(
fsqr(static_cast<double>(v))
/
fsqr(static_cast<double>(c))
);


Zmień też "1" na "1.0" w linijce poniżej (liczenie lambda).

Po co to wszystko? Kompilator ma swoje reguły konwersji i kolejności działań. Niestety nie zawsze te reguły są zgodne z intencjami autora, dlatego nawet jeśli perfekcyjnie je znasz, lepiej je wymusić - nawiasami i jawną konwersją.Piotr L. edytował(a) ten post dnia 25.10.11 o godzinie 21:06
Tomasz G.

Tomasz G. programista,
konstruktor
elektronik

Temat: Problem z liczeniem małych liczb

Faktycznie działanie
(v^2)/(c^2)

da zawsze zero w podanym przypadku dla v i c zadeklarowanych jako int, jako że v jest zawsze mniejsze od c a kompilator zapewne nie zrzutuje automatycznie na double bo i po co.
Ja bym zamiast jawnego rzutowania po prostu zadeklarował te zmienne jako double.

PS. Pozostał bym też przy C, nie przy C++ pomimo użycia streamów. Za prosty to przypadek.Tomasz G. edytował(a) ten post dnia 20.03.11 o godzinie 14:02

konto usunięte

Temat: Problem z liczeniem małych liczb

Tomasz G.:
Faktycznie działanie
(v^2)/(c^2)

da zawsze zero w podanym przypadku dla v i c zadeklarowanych jako int, jako że v jest zawsze mniejsze od c a kompilator zapewne nie zrzutuje automatycznie na double bo i po co.
Ja bym zamiast jawnego rzutowania po prostu zadeklarował te zmienne jako double.

PS. Pozostał bym też przy C, nie przy C++ pomimo użycia streamów. Za prosty to przypadek.

Jeśli już wchodzimy w szczegóły całości, to

1. c powinno być stałą.

const int c = 299792458;

lub lepiej

const double c = 299792458.0;


tak samo jak jego pochodne:

const double cd2 = c / 2.0;
const double cpow2 = fsqr(c);


2. "double argument" powinno być poza pętlą, a w niej tylko zmiana wartości

3. "return" powinno zwrócić stałą:


return EXIT_SUCCESS;


4. Stała PI jest niepotrzebna

Itd... ale nie chciałem zniechęcać.Piotr L. edytował(a) ten post dnia 25.10.11 o godzinie 21:06

Następna dyskusja:

Problem z dynamicznym przyd...




Wyślij zaproszenie do