Problemy początkującego programisty...

Odpowiedz Nowy wątek
2017-04-26 09:09
0

Witam wszystkich,

Od razu mówię, że jestem totalnym żółtodziobem, który rozpoczął przygodę z programowaniem w zeszłym tygodniu.

W ramach ćwiczeń napisałem sobie mały programik liczący ilość ziaren jaka znalazła by się na ostatnim polu szachownicy gdyby na każdym kolejnym znajdowała się liczba dwukrotnie większa niż na poprzednim (znana przypowieść o mędrcu i cesarzu).

Problem polega na tym, że program zlicza wartość jedynie do 30 pola czyli do wartości 1073741842, potem na polu 31 jest -2147483648 a następnie już same 0.

Proszę o podpowiedź jaką bibliotekę zastosować, zliczał powyżej tej liczby lub o krótkie wyjaśnienie zagadnienia.

Oto kod:

#include <iostream>
#include <conio.h>
#include <windows.h>

using namespace std;

int ziarenka=1, pole=0;

int main()
{
 cout <<"Program zliczajcy ziarenka ryzu:"<<endl;

 cout <<endl;

 while(pole<=63)
 {
    Sleep(500);
    pole++;
    ziarenka = ziarenka *2;
    cout <<"Numer pola: " <<pole <<", Ilosc ziarenek: "<<ziarenka <<"."<<endl;
 }

getch();
return 0;
}

Dziękuję z góry za pomoc i życzę miłego dnia,
AC

Pozostało 580 znaków

2017-04-26 09:12
1

Swego czasu korzystałem z:

https://mattmccutchen.net/bigint/

Możesz zerknąć, powinno się nadać.

Pozostało 580 znaków

2017-04-26 09:22
1

Ja bym skorzystał z long int, przydatny link:
https://www.tutorialspoint.com/cplusplus/cpp_data_types.htm

Tylko, że jak teraz się przyjrzałem to musisz szukać na polu 63, to albo musisz skorzystać z jakiejś biblioteki np. BIGNUM, albo zrobić strukturę do przechowywania takiej dużej liczby.


"Chodzenie po wodzie i tworzenie oprogramowania wg specyfikacji są łatwe, o ile woda i specyfikacja są zamrożone" - Edward V. Berard
edytowany 1x, ostatnio: Madaoo, 2017-04-26 09:47

Pozostało 580 znaków

2017-04-26 09:23

Problem związany jest z przekroczeniem maksymalnej wartości jaką może przyjąć int równą 2'147'483'647.
Możesz zamiast int użyć unsigned int, wtedy zakres będzie od 0 do 4'294'967'295.
Poczytaj sobie o podstawowych typach zmiennych.
Zamiast zmiennej int użyj np unsigned long long.


"Jesteśmy świadomymi istotami, a życie jest sposobem w jaki wszechświat poznaje sam siebie." prof. Brian Cox
edytowany 2x, ostatnio: bl4ster, 2017-04-26 09:44
2 ^ 64 nie zmieści mu się nawet w unsigned long long ;-) - Sparrow-hawk 2017-04-26 09:30
Racja, nie zwróciłem uwagi, że ilość pól to 63, w takim razie, to nie można tego zadania wykonać z wykorzystaniem standardowych typów zmiennych, które mają do 8 bitów. - bl4ster 2017-04-26 09:39

Pozostało 580 znaków

2017-04-26 09:48
1

boost multiprecision

Pozostało 580 znaków

2017-04-26 09:51
1
Madaoo napisał(a):

Ja bym skorzystał z long int, przydatny link:
https://www.tutorialspoint.com/cplusplus/cpp_data_types.htm

obawiam się, że może nie pomóc, w wielu kompilatorach long int to 4 bajty... Jeśli jest to raczej powinien skorzystać z typu uint64_t by miec pewność co do zakresu niezależnie od kompilatora! Ale chyba to też może być za mało


Ogólnie na prace domowe mam stawki zaporowe. Czasem coś o programowaniu znajdzie się na mojej stronie
edytowany 1x, ostatnio: kaczus, 2017-04-26 09:52

Pozostało 580 znaków

2017-04-26 09:59
1

Dziękuję wszystkim za odpowiedzi.

Na tym etapie mojej wiedzy (czytaj: bliska 0) zastosowanie "unsigned long long" wystarczy do dalszej pracy.

Pozdrawiam,
AC

Pozostało 580 znaków

2017-04-26 10:09
0

Ewentualnie w warunku pętli zmniejsz sobie ilość pól, tak, żeby nie przekroczyć w zmiennej ziarenka maksymalnej wartości.


"Jesteśmy świadomymi istotami, a życie jest sposobem w jaki wszechświat poznaje sam siebie." prof. Brian Cox
Można, jednak szachownica jak wiemy ma 64 pola ;) - dzięki. - AlphaCentauri 2017-04-26 10:14

Pozostało 580 znaków

2017-04-26 13:54
kq
1

uint64_t zdecydowanie wystarczy, na polu n jest 2n-1 ziaren.

Pole Ziaren
1 1 (20)
2 2 (21)
3 4 (22)
4 8 (23)
... ...
63 262
64 263

Pozostało 580 znaków

2017-04-26 14:17
0

Witam,

Trochę cierpliwości i znalazłem jeszcze inną odpowiedź na swoje pytanie:

Należy uruchomić bibliotekę #<iomanip>
Następnie w kodzie zamiast int wpisujemy long double
Na samym końcu wprowadzamy funkcję setprecision(10000);

Docelowo powinno to wyglądać tak i działa bez zarzutu:

#include <iostream>
#include <conio.h>
#include <windows.h>
#include <iomanip>

using namespace std;

long double ziarenka=1, pole=0;

int main()
{
 cout <<"Program zliczajcy ziarenka ryzu:"<<endl;

 cout <<endl;
 cout <<setprecision(10000);

 while(pole<=63)
 {
    Sleep(250);
    pole++;
    ziarenka = ziarenka *2;
    cout <<"Numer pola: " <<pole <<", Ilosc ziarenek: "<<ziarenka <<"."<<endl;

 }

getch();
return 0;
}

Dziękuję raz jeszcze wszystkim za podpowiedzi!

Pozdrawiam,
AC

Pomijając oczywiście fakt, że zawyża dwukrotnie wyniki ;-) - Sparrow-hawk 2017-04-26 15:16

Pozostało 580 znaków

2017-04-26 14:54
kq
2

Uważaj z używaniem liczb zmiennoprzecinkowych. Akurat w przypadku pełnych potęg dwójki to nie jest problem, ale jeśli np. zmodyfikujesz zadanie i będziesz chciał 3x więcej na każdym polu niż na poprzednim, to nagle okaże się, że double nie jest dostatecznie precyzyjny (np. sprawdź, czy pow(2,63) == pow(2,63)-1 na Twojej architekturze)


Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0