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

Projekt- Kalkulator

Ostatnio zmodyfikowano 2009-11-28 22:18
Autor Wiadomość
naiL
Temat założony przez niniejszego użytkownika
Projekt- Kalkulator
» 2009-11-16 23:43:08
Witam. Tak więcej główkując niż się realizując w c++ próbuję doścignąć forumowiczów w odrabianiu lekcji.:) Funkcje...
Próbuję zrobić kalkulator. Póki co mam spory problem ze zrozumieniem dodawania dużych liczb double :). Może to durne co niżej się znajdzie w tym poście ale:
kalkulator ma działać jak kalkulator. wprowadzam cyfry 0-9. przecinek mogę wprowadzić tylko raz. liczby będą posiadały exp. jeśli wartość będzie nie do wyświetlenia w postaci 10 cyfr z przecinkiem.
Do tej pory udało mi się zrealizować w taki sposób wprowadzanie cyfra po cyfrze liczby double z wykorzystaniem przecinka(tylko raz bo się brejkuje pętla) i dodaniem niestety tylko dodatniej exp. cout.precision(11)pozwala wyswietlić 10 cyfr+przecinek+ ewentualnie eXXX.
ok do dzieła... o to fragment odrębnego programiku który w taki sposób wczytuje
double a:
C/C++
#include <iostream>
#include <conio.h>
#include <cmath>
int main()
{
    double a = 0;
    int klawisz = 0;
    int flaga_przecinek = 0;
    int power = 0;
    int exp_power;
    std::cout << "wprowadz z klawiatury 10 cyfr. enter->wynik.\n \",\"-przecinek(drugi przecinek przerywa program. e-wprowadzenie wykladnika\n";
    for( int i = 0; i < 10; i++ )
    {
        klawisz = getch();
        if( !( klawisz >= 48 && klawisz <= 57 || klawisz == 44 || klawisz == 13 || klawisz == 101 ) )
        { i--;
            std::cout << "hmm...\n";
        }
        {
            if( klawisz == 101 )
            {
                std::cout << "podaj e-";
               
                std::cin >> exp_power;
                a = a * pow( 10, exp_power );
                break;
            }
            if( klawisz == 44 && flaga_przecinek == 1 ) break;
           
            if( klawisz == 44 && flaga_przecinek == 0 )
            {
                power++;
                flaga_przecinek = 1;
                i--;
            }
           
            if( klawisz == 13 ) break;
           
            std::cout << "kolejny klawisz \n";
            if( flaga_przecinek == 0 && klawisz >= 48 && klawisz <= 57 ) a = a * 10 +( double )( klawisz - 48 );
           
            if( flaga_przecinek == 1 && klawisz >= 48 && klawisz <= 57 )
            {
                a = a +(( double )( klawisz - 48 ) / pow( 10, power ) ); power++;
            }
        }
    }
    std::cout.precision( 11 );
    std::cout << a;
   
    getch();
    return( 0 );
}
w głównym programie używam dwóch funkcji:

C/C++
double liczbaA( double liczba_A, int klawisz )
{
    liczba_A = liczba_A * 10 +( double )( klawisz - 48 );
    return liczba_A;
}

double liczbaA_( double liczba_A, int klawisz, int potega )
{
    liczba_A = liczba_A +(( double )( klawisz - 48 ) / pow( 10, potega ) );
    return liczba_A;
}
do których dostarczana jest zależnie od tego czy był wciśnięty przecinek
wartość klawisz i ewentualnie potega. Potega na poczatku równa jest 0. po wcisnieciu klawisze "," zaznaczam sobie flagę że przecinek był wciśnięty

C/C++
if( klawisz >= 48 && klawisz <= 57 && flaga_przecinek == 0 ) liczba_A = liczbaA( liczba_A, klawisz );

if( klawisz >= 48 && klawisz <= 57 && flaga_przecinek == 1 ) liczba_A = liczbaA_( liczba_A, klawisz, pow );

wszystko jest cacy do momentu wprowadzenia <8 cyfr.
9cyfrowa liczba jest źle kalkulowana
nie wiem czy sam zapis (double)(klawisz-48) czegoś nie psuje.
chociaż w pierwszym "podprogramie" niby wszystko cacy biega.
P-11618
DejaVu
» 2009-11-17 04:29:46
Użycie typu double ma to do siebie, że możesz zapisać dużą liczbę, jednak kosztem dokładności. Tak więc testując swój program wyszło na to, że znalazłeś ograniczenie typu double i teraz będziesz prawdopodobnie tego świadom.

/edit:
Swoją drogą można inaczej wczytywać liczby double. Możesz wczytać ją najpierw całą wartość jako tekst, a następnie zamienić ją na liczbę. Możesz do tego użyć zarówno std::stringstream (jeśli piszesz w C++ to warto z tego skorzystać) lub funkcji atof (ale co do nazwy nie jestem w 100% pewien i nie chce mi się sprawdzać).
P-11619
naiL
Temat założony przez niniejszego użytkownika
» 2009-11-17 08:57:23
ok. cały urok kalkulatora polega na tym że nie wie jaką liczbę ostatecznie podam do momentu wybrania działania. :) wprowadzając liczbę cin >> string ->"1234567890" zamieniam to na double(jest faktycznie taka sprawa double atof ( const char * str ); tylko że nie będe miał urokliwego interfejsu output graficznego który po kolejnych wprowadzeniach wyświetla 1, jak do tego dołożę 2 wyświetli przesuwając 1 w lewo 12, 3-> 123 itd itd. dziwi mnie to że w prostym programiku działa to bez zarzutu w całym większym kodzie nie. Czy może być to wina kompilatora lub jego ustawień. czy devC++ może mi jakoś na bierząco zwracać wartości zmiennych które wykorzystywane są w programie? Jak to zrobić.?
Może faktycznie zamiast krok po kroku wyliczać double parafunkcją dokładać do string kolejne cyfry(i tak jest to kod asci). potem po wybraniu działania dopiero konwertować do double. Musiałbym jednak dokładać jakieś flagi(znak+/-, e+/-)
"999999999.9e99"/"-9999999999.9e-99" taką maksymalnie liczbę chce pobierać/wyświetlać po działaniu w kalkulatorze. możliwe że inny typ zamiast double?
P-11623
DejaVu
» 2009-11-17 10:53:43
Jeśli w małym programie działa to i w dużym powinno działać tak samo. Kompilator nic nie popsuje - przynajmniej nie ma on takich tendencji. Zdarzało mi się nie raz w swojej przeszłości zwalać coś na kompilator, jednak zawsze to ja gdzieś robiłem jakiś błąd. Po przeczytaniu Twojej treści raczej zrozumiałem, że problem pojawia się gdy libczby są większe niź X znaków, a nie że źle działa algorytm w jednym programie, natomiast w drugim działa poprawnie.
P-11624
Elaine
» 2009-11-17 11:38:35
gcc 3.4.2 może popsuć - źle oblicza długości skoków oraz adresy zmiennych na stosie...
P-11627
naiL
Temat założony przez niniejszego użytkownika
» 2009-11-17 20:39:16
ehh. no aż mi się odechciało dalej ślęczeć nad wyłuskaniem błędu wprowadzenie 99999999(8-dziewiątek)daje 100000000 +1 wartość większą.
22222222-22222222
222222222-222222224(+2)
33333333-33333332 (-1)
333333333-333333312(-12)
44444444-44444444
444444444-444444448(+4)
55555555-55555556(+1)
888888888-888888896(+8).
no spróbuję napisać to poprostu od nowa. to chyba jedyne rozwiązanie :(
P-11633
DejaVu
» 2009-11-18 00:26:42
Wczytuj najlepiej najpierw całą liczbę do zmiennej np. std::string (znak po znaku) zamiast przeliczać wartość w sposób, który zaprezentowałeś. Jeśli bedziesz miał już całą liczbę w std::string, przekonwertuj ją za pomocą std::stringstream na dowolny typ. Prawdopodobnie to rozwiązanie zadziała lepiej od tego, które Ty zrealizowałeś.
P-11643
naiL
Temat założony przez niniejszego użytkownika
» 2009-11-18 12:46:21
założenie było takie: uzyskać liczbę typu double(jeśli ma być ujemna *-1 po wciśnięciu znaku +/-) Liczba_A=Liczba_B. i po wciśnięciu którejś z opcji +/-/*///sin/cos/itp co tam tylko sie zmieści i dam rade wyliczyć sobie(niestety z braku pomysłowości nie wyobrażam sobie zaimplementowania kolejności wykonywanych zadań w sumie szkoda czasu lepiej nauczyć się lekcji dalej lekcjie XVII ;))ma być na nowo wczytywana liczba_A. Wynik np Libcza_B-Liczba_A czy cośtam miała być konwertowana w string i na zasadzie string.size() określana długość w cyfrach wyniku(max10)+przecinek+znak+/- +exp max99. No zadanie wyznaczyłem sobie trochę przerastające moje znajomości programowania ale każdy etap pracy który wychodzi satysfakcjonuje bardzo :) tu zonk jakiś powstał bo niby cacy a się okazuje że są sprawy nie do przeskoczenia. Mam juz wizję s1 typu string znak po znaku s1+s2(gdzie s2 to kolejna wprowadzana cyfra i tak to są kody asci także pewnie nie będzie to takie trudne) potem właśnie konwersja s1 do liczba_A(double). muszę na sucho sobie poćwiczyć. Dzięki. Jak będę miał jakiś większy wynik postaram się zamieścić programik w naszych pracach(ale z góry uprzedzam że to bardzo amatorski kalkulator:)).
pozdrawiam.na!L
P-11648
« 1 » 2 3 4
  Strona 1 z 4 Następna strona