nanoant20 Temat założony przez niniejszego użytkownika |
ustawianie precyzji dla typu float » 2019-11-21 12:20:27 Jak ustawić wyświetlanie liczb rzeczywistych z czterema cyframi po przecinku dla typu float? #include <iostream> #include <iomanip>
using namespace std;
int main() { float num1 = 20.7774, num2 = 2077.7774, num3 = 12345.7774, num4 = 123456.7774, num5 = 1234567.7774; cout << setprecision( 4 ) << fixed; cout << "num1 = 20.7774 \t\t" << num1 << endl; cout << "num2 = 2077.7774 \t" << num2 << endl; cout << "num3 = 12345.7774 \t" << num3 << endl; cout << "num4 = 123456.7774 \t" << num4 << endl; cout << "num5 = 1234567.7774 \t" << num5 << endl; cout << "" << endl; getchar(); return 0; }
Jest to dla mnie bardzo ważne, żeby dostawać po przecinku .7774 czyli dokładnie to co wpisze user a nie np .7773 czy .7812 .7500 |
|
darko202 |
» 2019-11-21 12:35:54 |
|
nanoant20 Temat założony przez niniejszego użytkownika |
» 2019-11-21 12:45:46 jest ustawiony setprecision, a ja nie będę posiadał wpływu na wartość jaką wpisze user //edit dobra juz sobie poradziłem zamiast 'float' użyje 'double' nara //edit 2 pytania 1. z ciekawości dlaczego tak dziwnie zachowuje się float? 2. chodzi o uzycie fabs? double fun( double x ) { long long int wynik = fabs( x * 10000 ); if( wynik % 10 >= 5 ) fabs( wynik += 10 ); return fabs(( wynik / 10 ) * 0.001 ); }
wyniki mam prawidłowe, ale czy można tak stosować? //EDIT przeczytałem i dziękuję @pekfos, @jankowalski25 za wyjaśnienia i poświęcony czas |
|
pekfos |
» 2019-11-22 21:18:06 1. z ciekawości dlaczego tak dziwnie zachowuje się float? |
Bo jest krótki. Typowo ma 32 bity i jest w formacie IEEE 754. Mantysa ma tam 23 bity. Weźmy te twoje 1234567.7774. Na start 1234567 to bitowo 1 0010 1101 0110 1000 0111. Zapisując to jako mantysa, najstarsza jedynka jest niejawna, więc zapisujemy 20 bitów. Zostają 3 na część ułamkową, a 0.75 to najlepsze przybliżenie 0.7774 jakie da się zapisać na 3 bitach. Tak działają liczby zmiennoprzecinkowe. Im większa liczba, tym mniejsza precyzja. Najlepszą precyzję masz między -1 i 1. if( wynik % 10 >= 5 ) fabs( wynik += 10 );
| wynik jest typu long long int, a używając fabs() na jakimś etapie przechodzi to przez liczbę zmiennoprzecinkową, więc możesz tracić dane. Powinieneś użyć std::abs(). |
|
jankowalski25 |
» 2019-11-22 21:41:52 Jak ustawić wyświetlanie liczb rzeczywistych z czterema cyframi po przecinku dla typu float? |
Precyzja liczb zmiennoprzecinkowych nie oznacza tego, co myślisz, że oznacza. Dokładność co do czterech cyfr oznacza tylko tyle, że możesz sobie dziesiątkowo wstawić dowolną czterocyfrową liczbę i postawić przecinek w dowolnym z pięciu miejsc. Czyli przykładowo: 2764 , 276.4 , 27.64 , 2.764 i 0.2764 to liczby, z których każda ma precyzję wynoszącą cztery. Jeśli chcesz mieć dowolne wartości zapisane z dokładnością co do czwartego miejsca po przecinku, to nic nie stoi na przeszkodzie, aby po prostu użyć liczb całkowitych o jakimśtam zakresie i przy wyświetlaniu uzyskiwać wartość przed przecinkiem jako liczba / 10000 oraz wartość za przecinkiem jako liczba % 10000 , natomiast same działania wykonywać normalnie na liczbach całkowitych. |
|
nanoant20 Temat założony przez niniejszego użytkownika |
» 2019-11-24 10:19:52 Nurtuje mnie jeszcze jedno pytanie. Wiadomo, że każdy typ ma określony zakres wartości, np. long long int Zakres: -9223372036854775808...9223372036854775807 unsigned long long int 0...18446744073709551615 i może się tak zdarzyć, przynajmniej hipotetycznie, że przy obliczeniach wynik może przekroczyć dozwolony zakres wartości dla danego typu, co prowadzi do błędów. I moje pytanie brzmi. Czy w jakiś sposób zabezpiecza się program przed takim nieokreślonym działaniem?
|
|
jankowalski25 |
» 2019-11-24 13:18:14 Tak. Mając minimum i maksimum (najlepiej wyciągnięte z std::numeric_limits ) oraz jasno zdefiniowane działanie, możesz przenośnie stwierdzić, czy wynik zmieści się w tym zakresie, czy też nie. Przykładowo przy dodawaniu dwóch liczb nieujemnych (unsigned) możesz odjąć od maksimum jeden ze składników i sprawdzić, czy drugi jest od tego większy. Jeśli jest, to na pewno nastąpi przekroczenie zakresu. |
|
nanoant20 Temat założony przez niniejszego użytkownika |
» 2019-11-24 14:29:56 @jankowalski25 dziękuję bardzo zadziałało, np size_t granica = numeric_limits < short >::max();
|
|
« 1 » |