liczby parzyste i nieparzyste na typie double

0

Witam!
mam problem mianowicie, nie wiem jak mam obliczyć czy podana jakas tam liczba przez uzytkownika jest parzysta czy nie ?? oczywiscie nie ma łatwo, zmienna jest typu double.

moze cos takiego:

#include <iostream>

using namespace std;

class liczba {
      private:
              double a;
              
      public:
             liczba();
             void wypisz();
             void dodatnia();
             void parzysta();
};

int main()
{
    liczba t1;
    t1.dodatnia();
    t1.parzysta();
    t1.wypisz();
    try { t1.wypisz(); }
    catch (...){ cout<<"liczba za duza"; } 

    system("PAUSE");
    return 0;
}

liczba::liczba(){
    cout<<"Podaj liczbe: ";
    cin>>a;

    if(a>1000)  throw 2;
    else a;
}

void liczba::wypisz(){
    cout<<"Podales liczbe: "<<a<<endl;
}

void liczba::dodatnia(){
    if(a>0) cout<<"Podana przez Ciebie liczba jest dodatnia\n";
    else cout<<"liczba nie jest dodatnia\n";
}

void liczba::parzysta(){
    double l;
    l=a%2;
    if(l==0)  cout<<"parzysta"; 
    else       cout<<"nieparzysta";
}

!!!!!!!!!!!!!!!!!!!!!!TU JEST TRESC ZADANIA W KOMENTARZU!!!!!!!!!!!!!!    
/*
klasa LICZBA. Schemat funkcjonalny
PRYWATNY składnik LICZBA typu double
konstruktor1 - prosi o podanie liczby
                       zgłasza wyjątek przy podaniu liczby >1000
metady publiczne:
wypisz - wypisuje liczbę
dodatnia - zwraca wynik: 1- tak, 0 - nie
parzysta - zwraca wynik: 1- tak, 0 - nie
*/

czekam na szybki odwet:D

pozdrawiam

0
  1. Co u ciebie znaczy "liczba parzysta" ?
  2. Sprawdź w słowniku co znaczy słowo "odwet".
0

poniatowski ty chyba nie wiesz co znaczy że "funkcja zwraca 1 lub 0"
To znaczy ze ty nie wypisujesz sobie w tej funkcji swoich dennych komentarzy, tylko funkcja zwraca pewien typ!
bool dodatnia();
bool parzysta();
!

bool liczba::dodatnia()
{
  if((this->a)>0) return true;
  else return false;
}

Rzutuj na inta i sprawdź czy to w ogóle jest liczba całkowita, jak jest to sprawdź reszte z dzielenia, jak nie jest to od razu zwróć false.

0

to jak mi ma teraz pokazywac wynik przez bool'a?? np

bool liczba::dodatnia(){
      if(a>0) return true;
      else return false;
}

teraz mam cos takiego:

#include <iostream>
using namespace std;
class liczba {
      private:
              double a;
              
      public:
             liczba();
             void wypisz();
             bool dodatnia();
             bool parzysta();
             };
int main()
{
  
  liczba t1;
  cout<<"liczba dodatnia: "<<t1.dodatnia()<<endl;
 
  
  cout<<"liczba parzysta: "<<t1.parzysta()<<endl;
   try {
       t1.wypisz();
       }
    catch (...){
                cout<<"liczba za duza";
                } 
                 
  system("PAUSE");
  return 0;
}

 liczba::liczba(){
           
      
           cout<<"Podaj liczbe: ";
           cin>>a;

           if(a>1000)  throw 2;
           else a;
           }
void liczba::wypisz(){
      
    
      cout<<"Podales liczbe: "<<a<<endl;
      }

bool liczba::dodatnia(){
      if(a>0) return true;  // 1 = dodatnia
      else return false;
     }

bool liczba::parzysta(){
      double l;
      
      if (a%2==0) return true; // 1 = parzysta
      else         return false;
} 

co o tym sadzicie?

na int'cie dziala ale na double dalej nie! wie ktos czemu

0

Liczby double to liczby zmiennoprzecinkowe. Nie można z nich korzystać do takich rzeczy jak określanie parzystości liczby, bo często zawierają one drobne przekłamania co w ogóle prowadzi do tego, że nie można rozstrzygnąć czy liczba jest w ogóle całkowita.

0

to moze źle zrozumiałem zadanie, mianowicie jest takie:

klasa LICZBA. Schemat funkcjonalny
PRYWATNY składnik LICZBA typu double
konstruktor1 - prosi o podanie liczby
zgłasza wyjątek przy podaniu liczby >1000
metady publiczne:
wypisz - wypisuje liczbę
dodatnia - zwraca wynik: 1- tak, 0 - nie
parzysta - zwraca wynik: 1- tak, 0 - nie
[???]

0

Przykro mi, ale Twój wykładowca jest upośledzony.
Zapewne chodzi oto żebyś użył funkcji truncate.

0

truncate? hm hm, ja tak trochę zadziwiony się czuję. No nie od dziś wiadomo, że operator modulo nie działa dla zmiennoprzecinkowych. Ale samo działanie istnieje, bo dlaczegóż by nie miało istnieć? Funkcji fmod się używa zamiast operatora %. Biorąc pod uwagę błędy, wyniku nie porównujemy z zerem oczywiście, tylko sprawdzamy "odległość od zera".

#include <iostream>
#include <cmath>
#include <limits>
using namespace std;

inline bool equal(double a, double b) {
    return fabs(a-b) < numeric_limits<double>::epsilon();
    }

inline bool is_even(double value) {
    return equal( 0, fmod(value, 2.0) );
    }

int main() {
    double number = 1.0;
    while( !equal(number, 0) ) {
        cin >> number;
        cout << is_even(number) << endl;
        }
    return 0;
    }
0

W ten sposób nie dowiesz się, czy liczba jest parzysta, czy prawie całkowita :/

0

Nie rozumiem cię adf'ie - wyjaśnij mi :)
Mam liczbę 4.0 - dla mnie zawsze będzie ona tyle równa, jeśli tylko będę brał pod uwagę tyle cyfr znaczących, ile trzeba. Może się zdarzyć, że nasze 4.0 != 4 ze względu na wewnętrzną reprezentację - ok. Ale dla mnie będzie równe 4. Dlatego używamy funkcji equal - ona usuwa nam problemy z wewnętrzną reprezentacją.

Jeśli weźmiesz prawie 4.0, ale takie prawie, że będzie równe 4+/-epsilon, no to z naszego punktu widzenia to jest 4. Że dla komputera 4.0 != 4 to już jego problem, nie nasz. A jak twoje prawie będzie się różnić bardziej, no to już mi to funkcja wykryje, i stwierdzi, że to nie jest 4.

0

Chodzi mi o to, że parzystość dotyczy liczby całkowitej, a jeśli działamy na zmiennoprzecinkowych to nie możemy rozstrzygnąć, że wynikiem jest liczba całkowita. Informacja, że jakaś liczba jest bliska liczbie parzystej jest zupełnie nie przydatna z matematycznego punktu widzenia.

0

czyli ostatecznie na co wychodzi?? ze cos z tym zadaniem jest nie tak, czy nie wiemy jak je rozwiazac??

0

ostatecznie wychodzi na to (i tu nawet adf88 się chyba zgodzi), że:
zadanie jest bez sensu, i rozwiązania nie ma, ale gdyby miało, to byłoby to moje rozwiązanie :D

a dla adf'a (wybacz, że tak odmieniam nick, ale lubię odmieniać nawet nieodmienialne) jeszcze dodam, że ja to widzę tak:

rozwiązanie jest w pełni poprawne matematycznie, pod warunkiem wprowadzenia dla liczb double relacji równości określonej warunkiem:
(a = b) <=> |a-b|<epsilon
takie wprowadzenie jest w pełni uzasadnione IMO właśnie ze względu na błędy reprezentacji i brak możliwości zdefiniowania relacji równości w inny rozsądny sposób. Operacja modulo, a raczej reszta z dzielenia również bez trudu może być rozszerzona dla liczb rzeczywistych, to raczej intuicyjne, ale możemy to zapisać choćby tak:
(a mod b) = a*b - floor(a/b)*b

I tak jeszcze w ramach ciekawostki, twierdzisz, że

Informacja, że jakaś liczba jest bliska liczbie parzystej jest zupełnie nie przydatna z matematycznego punktu widzenia.

to na takiej zasadzie, również informacja, że iloraz dwóch liczb rzeczywistych jest bliski liczbie wymiernej również nie miałby sensu. A sens ma w praktyce jak najbardziej - zobacz takie zjawisko jak krzywe Lissajous. Krzywe odpowiadające 1/2 wychodziły nam dla 512Hz/980Hz. I na przykład tutaj, w interpretacji fizycznej cały czas się siedzi na przedziałach i można powiedzieć, że była to "liczba wymierna z dokładnością do 5%" ;)

0

Resztę z dzielenia a przez b dla typów całkowitych i liczb dodatnich definiuje się tak: weźmy największą liczbę całkowitą k taką, że kb<=a, resztą z dzielenia jest a-kb. Te definicja ma sens również dla liczb z częścią ułamkową. Nie trzeba wymyślać nowej definicji.
Definicja ta jest tak naturalna, że porządne ;-) języki programowania (Java,Python) dopuszczają stosowanie operatora reszty z dzielenia dla typów zmiennoprzecinkowych.
Wynikający z definicji algorytm liczenia reszty z dzielenia liczby a przez liczbę dodatnią b jest taki

while(a<0)
   a+=b;
while(a>b)
   a-=b;
return a;

Powyższy algorytm jest bardzo mało wydajny, konkretna implementacja jest zatem na pewno inna. Implementacja musi też sobie radzić z ujemnym b.
Java: 3.23 % -1.27 = 0.69
Python: 3.23 % -1.27 = -0.58

0

Chorym bym był, gdybym w tak filozoficznej dyskusji głosu nie zabrał..., ale tego co ja tego ten miałem powiedzieć...?
Rani i Bogi ( :-) łot taka familiarna odmiana, ale chyba mogę tak po starej znajomości) przypomnieli,
że: m%n\equ m-\lfloor\frac{m}{n}\rfloor\cdot{n}
gdzie \lfloor\cdots\rfloor to floor() czyli część całkowita z...
Nie zależnie od tego jak liczy nasz komputer, można chyba (napisałem, że chyba bo to hipoteza, ale to ma być twierdzenie) określić liczby całkowite, nawet wśród zmiennoprzecinkowych, no można mieć inne np. wymierne, ale tu to nawet łatwiej.

Rani napisał(a)

inline bool equal(double a, double b) {
return fabs(a-b) < numeric_limits<double>::epsilon();
}

Czym jest ów ypsylon, bom nie jest tak oblatany, nie zależy od "a" czy "b" czyli magiczny jakiś, bezwzględny, ale... liczba to przecie x\cdot\mbox{cos tam}^y, a "x" i "y" całkowite z natury.
Niby IEE... "x" określa jako ułamek równy 1+coś tam po przecinku, ale to na jedno wychodzi, ale ale co z zerem? Ano zero zwykle jest liczbą szczególnej troski...
No to mamy zero równe zero, tu już nie ma mowy o epsach czy około równe..., jest zero albo nie i już.
...
Wasze zdrowie :-) pomyślę o zerze, myślę że coś z niego wynika.

O, przypomniał mi się, z tego, że m%n\equ m-\lfloor\frac{m}{n}\rfloor\cdot{n} wynika coś także dla liczb całkowitych.
Lubię duże liczby, a tam często po łyżce do butów trza coś wtyknąć do komurki, kompilator udaje, że nie wie o co mi chodzi, no to muszę go oszukiwać: pojawia się coś na kształt: a=x div y; b= x mod y;
Czyli X dzielę przez cóś i liczę resztę z dzielenia X przez cóś, jedno i drugie robię za jednym zamachem, ale kompilatory z którymi miałem do czynienia tego nie widzą, (mimo, że znają DivMod) i dwa razy dzielą.

(Sprawdźcie proszę jak wasz kompilator to robi) Np. liczę silnię, optymalnie liczyć dwójkowo, ale później chcielibyśmy zobaczyć wynik dziesiętnie i zamiana może (i zwykle) pożreć cały zysk.

A dzielenie przez STAŁĄ, szczególnie gdy STAŁA jest stała można zastąpić mnożeniem, a tranzystorom łatwiej mnożyć niż dzielić. Jak mówiłem, nie jestem oblatany, ale czuję, że nie zmieniło się zbyt wiele od:Link<url></url>

user image

No i jeszcze jedno, uprosiłem, może nie tylko ja, ale wreszcie znaczniki <tex> oraz </tex> ziałają. \e^{\Pi\cdot{i}}+1=0

0

Z matematycznego punktu widzenia wszystko jest ok - liczba rzeczywista (wymierna) może być liczbą parzystą. I analitycznie da się to sprawdzać. Liczby double reprezentują w pewnym przybliżeniu liczby rzeczywiste. Ciało liczb, które tworzą jest bardzo ubogie, nie ma tu przemienności, łączności i wielu innych cech, a wszędzie w obliczeniach traktujemy je jak pełnoprawne liczby rzeczywiste.

Chodzi o to, że liczba double będzie wynikiem obliczeń, pomiaru itp. Nigdy nie będziemy mieli pewności, że jest to liczba 100% dokładna. Owszem, możemy sobie zdefiniować liczbę np. 2.0, powiedzieć, że jest to dokładnie 2.0. Ale jaką ta liczba niesie informacje oprócz tego, że "jest" ? Żadnej. Czyli z informatycznego punktu widzenia jest kompletnie nieprzydatna. Również nieprzydatna jest informacja, że ta liczba jest parzysta, a jest to jedyny przypadek, gdzie da się to rozstrzygnąć. Dlatego dywagacje nt. zera są chybione:

Mag.Dobrowolski napisał(a)

No to mamy zero równe zero, tu już nie ma mowy o epsach czy około równe..., jest zero albo nie i już.

Możemy rozstrzygać czy liczba double jest w przybliżeniu parzysta. To już nie jest to samo co parzystość !

Parzystość niesie nam sporo przydatnych informacji. Parzystość w przybliżeni już prawie żadnej.

Ranides coś tam wynalazł o Krzywych Lissajous'a. Jednak w przyrodzie parametr krzywej nigdy nie będzie liczbą wymierną, co najwyżej dostaniemy jakieś sprzężenie zwrotne utrzymujące układ w równowadze. Analitycznie będzie dało się sprawdzić, czy sprzężenie utrzyma układ w równowadze. Numerycznie za pomocą komputera nie będziemy mieli nigdy pewności.

0

ta teoria do tego prostego zadania duzo pewnie poniatowskiemu nie pomoze ;) a wiec moja propozycja:
masz np. double n = 2.1234, odejmujesz od niej reszte po przecinku (czyli n mod 1). To co otrzymales spawdzasz mod 2 czy jest parzysta czy nie. To wszystko. Moze to np. tak wygladac w c:

double number = 7.1234;
double tmp = fmod(number - fmod(number,1.0),2); 
if(tmp == 0.0) cout << "parzysta";
else cout << "nie parzysta";
0

dzieki za pomoc Wam! mysle ze wszystko sie przyda, nawet sucha teoria :D pozdrawiam

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