Strona 1 z 1

[C++] Obcięcie dalszych miejsc dziesiętnych floata

: 29 sty 2015, o 16:06
autor: musialmi
C++ na ekran wyświetla 6 miejsc po przecinku. Zatem obchodzą mnie tylko one. Chciałbym, żeby liczby, które wyglądają jak całkowite, wyświetlały się jako całkowite. Wymyśliłem sposób, tylko on sobie nie działa.
Mam liczbę float, która wyświetla się jako -1.000000. Nazwijmy ją "a". Postanowiłem ją potraktować sposobem, który wymyśliłem:

Kod: Zaznacz cały

int c=1000000*a;
a=(1.0*c)/1000000;
Czyli najpierw zbieram z a pierwsze 6 miejsc dziesiętnych (ewentualnie z wcześniej czymś jeszcze, tutaj -1), a potem mnożę tę liczbę przez 1.0, żeby znów otrzymać liczbę zmiennoprzecinkową i dzielę to przez milion. Powinienem wg mnie otrzymać okrągłe -1.000000. Ale niespodziewanie dostaję -0.999999. Mam dwa pytania:

1. Jak obciąć dalsze miejsca dziesiętne?
2. Czyżby int zapamiętywał jednak miejsca dziesiętne i zostają one "odblokowane" podczas mnożenia przez 1.0?

[C++] Obcięcie dalszych miejsc dziesiętnych floata

: 29 sty 2015, o 18:04
autor: Dasio11
1. Nie da się obciąć miejsc dziesiętnych w liczbie zmiennoprzecinkowej, bo te liczby nie są trzymane w postaci rozwinięcia dziesiętnego, tylko dwójkowego. Każdy float reprezentuje liczbę postaci

\(\displaystyle{ (-1)^s \cdot 2^c \cdot \left( 1 + \frac{a_1}{2} + \frac{a_2}{4} + \ldots + \frac{a_{23}}{2^{23}} \right),}\)

gdzie \(\displaystyle{ s, a_1, \ldots, a_{23} \in \{ 0, 1 \}}\) oraz \(\displaystyle{ c \in \{ -127, \ldots, 127 \}.}\) (Są jeszcze wartości specjalne, ale mniejsza o to).

Nie można więc dokładnie zapisać liczby -0.999999, bo ona nie jest tej postaci (nie jest ułamkiem o mianowniku \(\displaystyle{ 2^{23}}\)).

2. Nie. Typ int pamięta tylko i wyłącznie liczby całkowite, bez ukrytych miejsc po przecinku.

Obliczenia na liczbach zmiennoprzecinkowych są nie do końca dokładne (chyba jest gwarancja, że błąd względny wyniku dodawania, odejmowania, mnożenia i dzielenia jest \(\displaystyle{ \le 2^{-23}}\)). Najwyraźniej wystąpił taki właśnie drobny (ale nieunikniony) błąd w obliczeniach.


3. Jeśli chcesz liczby zmiennoprzecinkowe wyświetlać z zadaną liczbą miejsc po przecinku, to możesz najpierw wpisać napis do tablicy:

Kod: Zaznacz cały

float a = -1.0;
char c[16];
sprintf( c, "%f", a );
a potem pokombinować z tym napisem zanim wypiszesz go na ekran.

[C++] Obcięcie dalszych miejsc dziesiętnych floata

: 29 sty 2015, o 20:11
autor: norwimaj
musialmi pisze: Mam liczbę float, która wyświetla się jako -1.000000.
Czyli może być równa na przykład \(\displaystyle{ rd_{\nu}(-0.9999999).}\)
musialmi pisze:

Kod: Zaznacz cały

int c=1000000*a;
a=(1.0*c)/1000000;
Jeśli \(\displaystyle{ a=rd_{\nu}(-0.9999999),}\) to \(\displaystyle{ c=999999.}\) Nie rozumiem, dlaczego nie sprawdziłeś wartości \(\displaystyle{ c}\) przed zadaniem pytania.
Dasio11 pisze:3. Jeśli chcesz liczby zmiennoprzecinkowe wyświetlać z zadaną liczbą miejsc po przecinku, to możesz najpierw wpisać napis do tablicy:
Jeśli chcemy \(\displaystyle{ 9}\) miejsc po przecinku, to możemy napisać printf ("a=%.9f
", a);

[C++] Obcięcie dalszych miejsc dziesiętnych floata

: 30 sty 2015, o 00:11
autor: Dasio11
norwimaj pisze:
Dasio11 pisze:3. Jeśli chcesz liczby zmiennoprzecinkowe wyświetlać z zadaną liczbą miejsc po przecinku, to możesz najpierw wpisać napis do tablicy:
Jeśli chcemy \(\displaystyle{ 9}\) miejsc po przecinku, to możemy napisać printf ("a=%.9f
", a);
Przez "zadaną" miałem na myśli, że może zależeć od liczby zer na końcu floata.
A printf ("a=%.9f
", a);
bezdusznie wyświetla 9 cyfr, czyli na przykład: -1 -> -1.000000000.