Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Problem z double (niedokładny wynik)

Ostatnio zmodyfikowano 2009-06-11 12:10
Autor Wiadomość
programator
Temat założony przez niniejszego użytkownika
Problem z double (niedokładny wynik)
» 2009-06-11 10:07:17
Witam, mam problem z prawidłowym działaniem programu, który oblicza pola trójkątów.
Zmienna double wyświetla mi liczby do 5 miejsc po przecinku (robiłem inny program).
w funkcji main mam daklarację:
C/C++
double a = 0, b = 0, c = 0, d = 0, Pole = 0;
oto jedna funkcja tego programu, oblicza pole....
C/C++
int oblicz_prownoramienny( int wybor )
{
    char tn;
    bool nif = true;
    short int strzalka = 0;
    short int n = 1;
    switch( wybor )
    {
    case 1:
        gwiazdki();
        cout << "Podaj wartos† dlugosci ramienia tego tr˘jkĄta:\n";
        gwiazdki();
        cin >> a;
        gwiazdki();
        break;
    case 2:
        gwiazdki();
        cout << "Podaj wartos† dlugosci przeciwprostok¤tnej tego tr˘jkĄta:\n";
        gwiazdki();
        cin >> b;
        gwiazdki();
        break;
    }
    TAKNIE( 1 );
    while( strzalka != 13 )
    {
        strzalka = getch();
        if( strzalka == 80 )
        {
            if( n > 0 && n < 2 ) n = n + 1;
           
            TAKNIE( n );
        }
        if( strzalka == 72 )
        {
            if( n > 1 && n < 3 ) n = n - 1;
           
            TAKNIE( n );
        }
    }
    if( strzalka == 13 )
    {
        if( n == 1 )
        {
            prownoramienny();
        }
        if( n == 2 )
        {
            gwiazdki();
            cout << "obliczam.....\n";
            if( a || a && b && nif )
            {
                ddt::console::textcolor( 10 );
                cout << a << " * " << a << " / 2 =....\n";
                ddt::console::textcolor( 14 );
                Pole = a * a / 2;
                cout << "Pole tego tr˘jkĄta wynosi: " << setprecision( 8 ) << Pole;
                cout << "\n";
                gwiazdki();
                nif = false;
                a = 0, b = 0, c = 0, d = 0, Pole = 0;
                getch();
            }
            if( b && nif )
            {
                ddt::console::textcolor( 10 );
                cout << b << " / sqrt(2) = " <<( b / sqrt( 2 ) ) << endl;
                cout <<( b / sqrt( 2 ) ) << " * " <<( b / sqrt( 2 ) ) << " / 2 =....\n";
                ddt::console::textcolor( 14 );
                a = b / sqrt( 2 );
                Pole = a * a / 2;
                cout << "Pole tego tr˘jkĄta wynosi: " << setprecision( 8 ) << Pole;
                cout << "\n";
                gwiazdki();
                nif = false;
                a = 0, b = 0, c = 0, d = 0, Pole = 0;
                getch();
            }
            if( !Pole && nif )
            {
                cout << "Z podanych danych nie moľna obliczy† pola tego tr˘jkĄta\n";
                gwiazdki();
                a = 0, b = 0, c = 0, d = 0, Pole = 0;
                getch();
            }
            koniec();
        }
    }
}
Problem jest w czasie obliczania.
Jeżeli zmienna b ma wartość 5, wykonywane są takie obliczenia:
5 / sqrt(2) = 3.5355339 // tu jest w porządku
3.5355339 * 3.5355339 / 2 = 6.25 //i tu jest problem....
Wynik powyższego działania to: 6,249999979024605
Ja bym chciał przynajmniej te 5 miejsc po przecinku....
A tu oblicza zaokrąglony wynik.
Dlaczego tak jest?
Próbowałem z biblioteką <iomanip> ale też taki wynik jest.
Bardzo proszę o pomoc.
Mogę także wrzucić na jakiś serwer cały program:)

P-7570
WunM
» 2009-06-11 10:27:15
Raczej to nie jest wina biblioteki tylko kompilatora. Na GCC wynik wychodzi 6.25 Dla pewności sprawdzałem w PHP5 i jest dobrze. Jak znajdę u siebie inny kompilator to spróbuję. Ale pewnie da się to obejść.
P-7571
programator
Temat założony przez niniejszego użytkownika
» 2009-06-11 10:33:38
Używam Dev-C++ do kompilacji.
Jeżeli to wina kompilatora, to czy można to jakoś zmienić (w ustawieniach) aby wyniki były dokładne?
Jak nie, to inny kompilator....?
P-7572
WunM
» 2009-06-11 10:48:12
Z dużymi liczbami o typach zmienno-przecinkowych tak jest. Spróbuj użyc w obliczeniach unsigned long long.

//edit

Zapomniałem że chcesz typ zmiennoprzecinkowy a nie całkowity.

signed long long
P-7573
programator
Temat założony przez niniejszego użytkownika
» 2009-06-11 11:16:28
C/C++
signed long long
traktuje jako typ całkowity....
unsigned też jako typ całkowity.

EDIT:
long double też przyjmuje wartość skróconą....
P-7574
DejaVu
» 2009-06-11 11:51:06
Wyświetlaj do 5 miejsc po przecinku to Ci zaokrągli wynik i będzie dobrze.
P-7576
programator
Temat założony przez niniejszego użytkownika
» 2009-06-11 12:02:18
Ale w jaki sposób?
korzystając z biblioteki <iomanip> też wyświetla mi 6.25:(
P-7578
programator
Temat założony przez niniejszego użytkownika
» 2009-06-11 12:17:04
prosty program:
C/C++
#include <iostream>
using namespace std;
int main()
{
    double b = 3.35335539;
    cout << "b * b = " << b * b << endl;
    system( "pause>>NULL" );
    return( 0 );
}
Z tego otrzymałem wynik 11.245
A powinno być więcej miejsc po przecinku....

//edit
Kurde, tutaj działa z <iomanip>....
Ale tutaj nie....
C/C++
#include<iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
    double a = 0, b = 5, Pole = 0;
    cout << "b= " << b << endl;
    cout << "a= " << a << endl;
    cout << "Pole= " << Pole << endl;
    cout << "Operacja pierwsza.....\n";
    a = b / sqrt( 2 );
    cout << "b= " << b << endl;
    cout << "sqrt(2)= " << sqrt( 2 ) << endl;
    cout << "a= " << a << endl;
    cout << "Druga operacja...\n";
    a = pow( a, 2 );
    cout << "a= " << a << endl;
    cout << "Pole= " << Pole << endl;
    cout << "Pole tego tr˘jkĄta wynosi: " << setprecision( 8 ) << a;
    system( "pause>>NULL" );
    return( 0 );
}
Co więc trzeba zrobić, żeby było dobrze?
P-7581
« 1 » 2
  Strona 1 z 2 Następna strona