modf i poprawny wynik części ułamkowej

0

napotkałem taki o to problem. może napiszę kod programiku pomocniczego i wynik:

#include <cmath>
#include <cstdio>

int main(int argc,char**argv)
{
	double liczba,calkowita,ulamek;
	
	printf("Podaj liczbe: ");
	scanf("%lf",&liczba);
	
	ulamek=modf(liczba,&calkowita);
	printf("%lf = %lf + %lf\n",liczba,calkowita,ulamek) ;
	
	liczba=ulamek;
	liczba*=10.0;
	
	ulamek=modf(liczba,&calkowita);
	printf("%lf = %lf + %lf\n",liczba,calkowita,ulamek) ;

	return 0;
}
Podaj liczbe: 3.3
3.300000 = 3.000000 + 0.300000
3.000000 = 2.000000 + 1.000000

to znaczy ja dobrze wiem z czego wynikają te błędy (a raczej niedokładności) przy mnożeniu przez 10.0, ale jak im zapobiec? czy trzeba za każdym razem wprowadzać tolerancję błędu i sprawdzać, czy:

(abs)(liczba-1.0)<EPSILON

czy może jest szybszy (a raczej gotowy) sposób?

0

Nie ma innego sposobu, ale raczej powinno być tak:

ulamek=modf(liczba,&calkowita);
if (liczba>=0) {
    if (ulamek>0.9999995) {
        calkowita+=1.0;
        ulamek = 0;
    }
} else {
    if (ulamek<-0.9999995) {
        calkowita+=-1.0;
        ulamek = 0;
    }
}

Błąd nie wynika z mnożenia przez 10 ale z reprezentacji binarnej 0.3 i zaokrągleń.

0

Możesz stworzyć typ ułamkowy reprezentujący liczbę rzeczywistą (takie coś występuje domyślnie w LISPie - nie wiem czy w C++ jest takie coś w std, ale napisanie to żaden problem).
Ogólnie chodzi o to że masz strukturę z polami licznik i mianownik.
Przeciążenia operatorów i gotowe - nie trzeba się już przejmować wewnętrzną reprezentacją floatów.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.