c++ ulamek czy calkowita???

0

witam

mam dosc dziwne pytanie?

"jak sprawdzic czy liczba jest ulamkiem czy jest calkowita ?" czy posiada znaczy sie cos po przecinku ?:P
czekam na jakis przykladzik ,fajny przykladzik :*

pozdrawiam
Moniczka

0

double liczba = 1..234;
if ((double)((int)liczba) == liczba) cout << "calkowita";
else cout << "z ulamkiem";

0

Od kiedy 2 double tak się porównuje ? w ogolnym przypadku nie mozna w ten sposob rzutowac/porownywac double'i :P

//q: dokladnie tak. nie jest to prawidlowe poniewaz raz, ze chwilowe przerzutowanie na int moze zaburzyc najmniej znaczace bity double'a, a dwa ze double moze trzymac wartosci duuuzooo wieksze niz int, long, czy long long

równość dwóch zmiennych double można co najwyżej sprawdzać w pewnym małym otoczeniu.
Jak już to:

const double eps = 0.0001;
if (fabs(liczba - floor(liczba)) < eps)

Innymi slowy, podstawy metod numerycznych się kłaniają :P
Jak ktoś nie wierzy daje kod:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>



void have(double liczba) {
    if ((double)((int)liczba) == liczba)  printf("calkowita");
    else printf("z ulamkiem");
}

void have2(double liczba) {
    const double eps = 0.0000000001;
    if (fabs(liczba - floor(liczba)) < eps) printf("calkowita");
    else printf("z ulamkiem");
}

int main(int argc, char** argv) {
    double liczba = 18446744073709551616.000000;
    have(liczba);
    printf("\n");
    have2(liczba);
    printf("\n%lf %lf", liczba, liczba - floor(liczba));
    return (EXIT_SUCCESS);
}
0

Kłania się również znajomość zakresów typów :>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>



void have(double liczba) {
    if ((double)((long long)liczba) == liczba)  printf("calkowita");
    else printf("z ulamkiem");
}

void have2(double liczba) {
    const double eps = 0.0000000001;
    if (fabs(liczba - floor(liczba)) < eps) printf("calkowita");
    else printf("z ulamkiem");
}

int main(int argc, char** argv) {
    double liczba = 18446744073709551616.000000;
    have(liczba);
    printf("\n");
    have2(liczba);
    printf("\n%.10lf %lf\n", liczba, liczba - floor(liczba));
    printf("\n%.10lf %lf\n", (double)((long long)liczba), (double)((long long)liczba) - floor((double)((long long)liczba)));
    system("pause");
    return (EXIT_SUCCESS);
}

Przy tej wartości przekręcisz nawet long long (więc nic dziwnego że daje zły wynik), ale zobacz sobie to

#include <stdio.h>
#include <stdlib.h>
#include <math.h>



void have(double liczba) {
    if ((double)((long long)liczba) == liczba)  printf("calkowita");
    else printf("z ulamkiem");
}

void have2(double liczba) {
    const double eps = 0.0000000001;
    if (fabs(liczba - floor(liczba)) < eps) printf("calkowita");
    else printf("z ulamkiem");
}

int main(int argc, char** argv) {
    double liczba = 8446744073709551616.000000;
    have(liczba);
    printf("\n");
    have2(liczba);
    printf("\n%.10lf %lf\n", liczba, liczba - floor(liczba));
    printf("\n%.10lf %lf\n", (double)((long long)liczba), (double)((long long)liczba) - floor((double)((long long)liczba)));
    system("pause");
    return (EXIT_SUCCESS);
}

Obie linijki dają taki sam wynik :-P

0

Akurat wkleiłem nie tą liczbę co chciałem, miał być 4294967295. I przy tym daje wynik poprawny.
A że 2 doubleów nie porównuje się nigdy bezpośrednio tylko w pewnym otoczeniu to jest chyba największa podstawa metod numerycznych, tego nawet w liceum uczą.

0

Dla wartości 4294967295 też działają oba sposoby, więc nie rozumiem o co caman.

Ja nie chodziłem do liceum, tylko technikum, więc mnie tego nie nauczyli ;)
A co do porównywania, to w rzeczywistości być może tak się powinno robić, bo wyniki rzeczywiste są ciągłe. W kompie, jak byś się nie starał, to i tak sposób zapisu tych liczb sprawia, że w są ziarniste i mają skończoną dokładność. A jako takie mogą być porównywane wprost.

0

Loloki, a teraz dam Ci zagadkę, do której nie użyjesz kompilatora, tylko mózgu
Powiedz, jaki wynik da następujący program i dlaczego:

#include <iostream>

using namespace std;

int main(){
    if(0.2 == 0.2) {
        cout << "T1" << endl;
    }
    if(1.2 - 1.0 == 0.2) {
        cout << "T2" << endl;
    }
    if((double) 1.2 - (double) 1.0 == (double) 0.2){
        cout << "T3" << endl;
    }
    return 0;
}
0
enter_sandman napisał(a)

A że 2 doubleów nie porównuje się nigdy bezpośrednio tylko w pewnym otoczeniu to jest chyba największa podstawa metod numerycznych, tego nawet w liceum uczą.
W tym przypadku może być inaczej. Zapis liczby zmiennoprzecinkowej się kłania. Jeśli bity mantysy odpowiedzialne za część ułamkową są wszystkie równe zeru to liczba ta jest całkowita. Każda liczba całkowita w postaci tekstowej lub liczba typu całkowitego (np. int) po przekonwertowaniu na liczbę zmiennoprzecinkową (float/double) nadal pozostaje liczbą całkowitą (w sensie zerowej części mantysy).

I teraz, czy będziemy porównywać dokładnie, czy z pewnym otoczeniem, zależy od tego co autorka chce osiągnąć. Generalnie sprawdzanie czy liczba zmeinnoprzecinkowa jest liczbą całkowitą raczej jest złym podejściem do problemu, który można rozwiązać w zupełnie inny dokładniejszy sposób.

@dodekam: problem zaokrągleń, który poruszyłeś wynika z konwersji pomiędzy systemem dziesiętnym a binarnym. Kod oglądamy w zapisie dziesiętnym i wydaje nam się, że 1.2 - 1.0 nie może dać innej liczby niż 0.2. Jeśli jednak zapisać by te liczby binarnie (a tak je komputer pamięta) to musielibyśmy użyć ułamka okresowego. Jak na razie procesory nie obsługują ułamków okresowych więc okres musi być ucięty. Tego problemu nie ma w przypadku stwierdzania czy liczba jest całkowita, czy nie. Jest tak dlatego, że liczba całkowita nigdy nie będzie ułamkiem okresowym, niezależnie od tego w jakim systemie ją zapiszemy. I nigdy nic nie zostanie ucięte. Zapis liczby zmiennoprzecinkowej pozwala to jasno określić. Nie istnieje podobny przykład z dodawaniem, odejmowaniem czy mnożeniem, gdzie posługując się liczbami całkowitymi (typu zmiennoprzecinkowego, np 1.0, -6.0, 15.0) wyprodukujesz w wyniku błędów zaokrągleń liczby z częścią ułamkową.

0

Boze jakie wy mądre chłopaki jestescie D:D ja chcialam tylko odroznic liczbe calkowiata od ulamka...czy cos jest po przecinku :) nie myslalam ze to takie trudne bedzie hihihi

pozdrawiam i buziam!!!

0

matko, adf, ja wiem, jak działa IEEE floating point, chciałem tylko ukrócić tego cwaniaczka, co twierdzi, że double mogą być porównywane wprost...

0

o losie.... ja prosty przykladzik dalem a tu taka burza, jakby laska znala sie ciun na metodach w dodatku numerycznych (!) to by nie pytala o "prosty przykladzik" ;p

0

Ale zaimponowaliscie kobiecie - tylko teraz sie nie pobijcie miedzy soba he he

0
cepa napisał(a)

jakby laska znala sie ciun na metodach w dodatku numerycznych (!) to by nie pytala o "prosty przykladzik" ;p

ej...nie mow na mnie laska...mam na imie Monika :) hihi kolega zazdrosci hihihi

buziam wszystkich :*

0
Moniczka napisał(a)

ej...nie mow na mnie laska...mam na imie Monika :)

o przepraszam Moniko ;-)

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