Coś nie tak z obliczaniem dni juliańskich

hej mógłby ktoś sprawdzić

#include

#include


main()

{

      double r,m,d,i,j,k,l,dj;

      float w;

      printf("Podaj rok: \n");

      scanf("%d", &r);

      miesiac:

      printf("Podaj miesiac: \n");

      scanf("%d", &m);

      while(m>12)

       { 

                 goto miesiac;

       }

       dzien:

       printf("Podaj dzien: \n");

       scanf("%d", &d);



       i=4716+floor((m+9)/12);

       j=1729279.5+367*r+floor(275*m/9)-floor(7*i/4)+d;

       k=floor((i+83)/100);

       l=floor(3*(k+1)/4);

       dj=j+38-l;

       w=dj+0.5;


       printf("Dni julianskie: %d \n", w);

}

gdy wpisuję datę 26.10.2005 wyświetla mi 0 a powinno wyświetlać 2453670.4528556713

W języku C dwa rodzaje dzielenia jedno normalne drugie całkowite (jak w podstawówce) oba zapisują się za pomocą tego samego znaku /. Jeżeli dzielnik oraz dzielna są liczbami całkowitymi to wykonuje się dzielenie całkowite, w przeciwnym przypadku dzielenie normalne.

np.

double x=7/2; // x=3

double y=7./2; // y=3.5

double z=7/2.; // z=3.5

double p=(double)7/2; // p=3.5

double q=7/(double)2; // q=3.5

skąpe te wyjaśnienia liczyłem na jakąś poprawkę w kodzie lub bliższe wytłumaczenie jak poprawić błąd

Przecież dałem 4 warianty jak ten błąd poprawić.

Aha dopiero zauważyłem, masz błąd wczytywania, dla wczytywania liczby double trzeba wykorzystać “%lf” w scanf.

scanf("%lf", &r);

ale w tym przypadku lepiej zmienić deklaracje r,m,d na unsigned ("%u" w scanf) aby użytkownik nie podał rok 3,14156294. Też warto dziwactwa typu:

miesiac:

      printf("Podaj miesiac: \n");

      scanf("%d", &m);

      while(m>12)

       {

                 goto miesiac;

       }

zamienić na:

while(true)

        {

         printf("Podaj miesiac: ");

         scanf("%u",&m); // unsigned m; // w deklaracji

         if((1<=m)&&(m<=12)) break;

         printf("Błąd przy wprowadzaniu miesiąca wartość musi być 1..12\n\n");         

        }

Albo co jeszcze lepiej zmienić wprowadzanie na:

#include 

#include 


int main()

  {

   unsigned r,m,d,i;

   char c1,c2;


   while(1)

      {

       printf("Podaj datę w formacie dd.mm.rrrr (!-koniec): ");

       int n=scanf("%u%c%u%c%u",&d,&c1,&m,&c2,&r);

       if((n==5)&&(c1=='.')&&(c2=='.')&&(1<=m)&&(m<=12)&&(1<=d)&& (d<=30+(m!=2?((m&1)!=(m>7)):-(((r&3)&&!(r%100)||(r%400))<<1)))&&(1<=r)) // sprawdzenia poprawności daty

         {

          i=(m+56601)/12;

          printf("Dni julianskie: %u\n\n",1729318+367*r+275*m/9+d-7*i/4-3*(i+183)/400);

         }

       else

         {

          c1=getchar();

          if(c1=='!') return 0;

          while(c1!='\n') c1=getchar();       

          printf("Błąd przy wprowadzaniu danych\n\n");

         }

      }   

  }

EDIT: wstawiłem pełne sprawdzenie poprawności daty.

EDIT2: dodałem uproszczone obliczenia

tylko że się nie chce skompilować na serwerze;/

W C nie ma true ani false, nie ma w ogóle typu bool (ale jest w C99 typ _Bool). Jednak jeżeli piszesz w C to użyj jedynki.

Niby racja, tylko że zwróć uwagę na kompilator który lukaszm używa - to gcc, dziwie się że ten kompilator nie rozumie bool.

13tySmok , nie mam starego komputera to po pierwsze a po drugie jest to serwer utworzony na uczelni

Kompilator to nie to samo co komputer :stuck_out_tongue:

gcc to kompilator języka C, a w C nie ma typu bool; W C bool, true i false to w pełni poprawne identyfikatory (np. zmiennej, funkcji lub struktury). Natomiast gdyby użył g++ - kompilatora C++ z pakietu GCC, wtedy kod by zadziałał, rozpoznając true jako zastrzeżone słowo języka.

Wszystko co powiedziałeś jest jak najbardziej poprawnie, tylko nie wiedzieć czemu wszystkie dostępne mi kompilatory gcc (pod windowsami, oraz na trzech serwerach pod unixem) rozpoznają elementy C++ (ustawienie domyślne), aby przestali rozpoznawać trzeba dać specjalną opcje (nie pamiętam jaką bo właściwie nigdy tego nie używałem).

lukaszm , nie powiedziałeś czy już po problemie. Ponieważ masz dziwne przepuszczenia :lol:

wg mnie (oraz matematyki) powinno wyjść dokładnie 2457194.

Nie mówiąc już o tym że całe obliczenia da się mocno skrócić:

unsigned d,m,r; // dzień, miesiąc, rok

unsigned i=(m+56601)/12;

printf("Dni julianskie: %u\n",1729318+367*r+275*m/9+d-7*i/4-3*(i+183)/400);

Hmm nigdy nie próbowałem pisać “C++ w C”. Szczerze mówiąc, nie słyszałem, żeby gcc domyślnie rozpoznawało elementy C++, bo jeżeli tak, to jakie? Chyba nie wszystkie, a jak wybrane to które? Mi zarówno gcc 4.2 jak i 4.3 nie rozpoznają true ani true, dostaję te same komunikaty co lukaszm. Jeżeli tak było to chyba zaostrzyli reguły, zauważyłem to, ale odnośnie kodu C w C++ (wcześniej można było używać wielu funkcji C w C++, teraz bez jawnego załączenia nagłówka się nie da w większości przypadków).

Znalazłem jest opcja -x:

-x Specify the language of the following input files

                           Permissible languages include: c c++ assembler none

                           'none' means revert to the default behavior of

                           guessing the language based on the file's extension

Więc kompilator sam zgaduje na podstawie rozszerzenia.

Co do próbowania pisania “C++ w C” to miałem z tym do czynienia, kiedyś dawno temu miałem specjalny cpp.h definiujący miedzy innymi bool jako char, true jako ‘\1’ oraz false jako ‘\0’. Z tym plikiem nagłówkowym pisząc w C używałem sobie bool, true, false i kilka innych innowacji z C++.

W trakcie bawienia się opcjami kompilatora problem lukaszm załatwiłem :lol: Podmieniłem wcześniejszą propozycje interfejsu na cały kod.