Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

ustawianie precyzji dla typu float

Ostatnio zmodyfikowano 2019-11-24 14:29
Autor Wiadomość
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?

C/C++
#include <iostream>
#include <iomanip>      //cout.setf(ios::fixed); cout.precision(3);

using namespace std;

int main()
{
    float num1 = 20.7774, num2 = 2077.7774, num3 = 12345.7774, num4 = 123456.7774, num5 = 1234567.7774;
   
    //Okreslam, staloprzecinkowe wyswietlanie liczb rzeczywistych
    //z czterema cyframi po przecinku
    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

P-175634
darko202
» 2019-11-21 12:35:54
P-175635
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?
C/C++
double fun( double x )
{
    long long int wynik = fabs( x * 10000 ); //o.k tak mozna
    if( wynik % 10 >= 5 ) fabs( wynik += 10 ); // tu chyba też
   
    return fabs(( wynik / 10 ) * 0.001 ); // ale czy tak return'em jest prawidłowo?
}
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
P-175637
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.

C/C++
if( wynik % 10 >= 5 ) fabs( wynik += 10 ); // tu chyba też

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().
P-175641
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.
P-175642
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?
P-175655
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.
P-175657
nanoant20
Temat założony przez niniejszego użytkownika
» 2019-11-24 14:29:56
@jankowalski25 dziękuję bardzo zadziałało, np

C/C++
size_t granica = numeric_limits < short >::max();
P-175658
« 1 »
  Strona 1 z 1