atof - problem 2.2 po konwersji jest 2.200000smieci...

0

Hey, mam problem z funkcją atof.

AnsiString liczba_tekst = "2.2";
float liczba = 0;
liczba = atof(liczba_tekst.c_str());
ShowMessage(liczba) //wynikiem jest 2.200000021341234

Powyzszy kod działa jakos dziwnie dla mnie...wprowadzam 2.2 a na wyjsciu mam cos podobnego ale nie dokładnie 2.2 Dlaczego wie ktoś moze??

Z góry dzięki

0

U mnie jest wszystko w porzadku.
Sprobuj wyswietlic "liczba_tekst.c_str()", sprobuj wyswietlic zmienna liczba, ale przypisz jej wartosc taka "liczba = atof("2.2");", bedzie mozna wtedy zdiagnozowac ktora czesc programu zawodzi.

0

Zamiast float użyj double. 'Śmieci' przesuną się w prawo, ale też zwiększy się precyzja. Float został wymyślony by polepszyć typ int, zachowując jego rozmiar.

atof zwraca double które nieumyślnie zmieniasz na float dodając owe śmieci na bardziej znaczące miejsca dziesiętne. Liczby zmiennoprzecinkowe nie są przechowywane jako zbiór cyfr dziesietnych.

Jeśli chcesz uzyskiwać maksymalną dokładność oferowaną przez procesor, to używaj funkcji i typów pełnowymiarowych, np. 80-bitowego 'long double', lub funkcji/klas które samodzielnie obliczają takie liczby z dużo większą precyzją - przykładowo Ldouble.

0

zawsze beda smiecie ze wzgledu na blad, zamiast konwertowac i wypisywac kazda cyfre zapisu dziesietnego uzyj notacji naukowej

0

zawsze można wyswietlić tekst a nie liczbę, czyli string->float->string, czy czym pierwszy string może być np. ciagiem z klawiatury, float wynikiem jakiegoś działania związanego ze stringiem pierwszym, a drugi string to konwersja wyniku z powrotem do stringa. To o tyle dobre rozwiązanie że panuje się nad dokładnością wyniku.

0
RR napisał(a)

zawsze można wyswietlić tekst a nie liczbę, czyli string->float->string, czy czym pierwszy string może być np. ciagiem z klawiatury, float wynikiem jakiegoś działania związanego ze stringiem pierwszym, a drugi string to konwersja wyniku z powrotem do stringa. To o tyle dobre rozwiązanie że panuje się nad dokładnością wyniku.

to byl zart, co nie?:) po co sie tak meczyc.. przeciez w C mozna do %f dopisac modyfikator precyzji, a w C++ uzyc manipulatora setprecision na cout'cie czy innym ofstream'ie..

0

quetzalcoatl a co ja napisałem?

a drugi string to konwersja wyniku z powrotem do stringa. To o tyle dobre rozwiązanie że panuje się nad dokładnością wyniku.

Najpierw pobierasz jako string (tak na wszelki wypadek, żeby idiotów wykluczyć, przy czym string to może być char* lub string, AnsiString itd) zamieniasz na float (lub inny typ) i dokonujesz jakichś obliczeń. Następnie z powrotem zamieniasz na string/char* itd żeby skorzystać z precyzji.
Zresztą co tu dużo gadać. Napisz program, który skorzysta z tej funkcji do wyświetlenia wyniku i uzyskaj precyzję, czyli np. pobierz do string, dodaj 2.06, wyświetl tą funkcją z precyzją do 3 miejsca.
Jeśli jesteś zmuszony to wykorzystania takiej funkcji to chciałbym zobaczyć jak to zrobisz, prócz metody string->float->string->wyswietl :)

void wyswietl(char *p)
{
   print("%s", p);
}
0

nie zaprzeczam ze czasem trzeba wpierw odczytac cstringa a potem go atof'owac na float, zamiast os razu czytac floata ze strumienia.

zaprzeczam jakoby trzeba bylo owego floata przerabiac na stringa celem uzyskania wskazanej precyzji wyswietlania.
dowod:
C: http://www.cplusplus.com/reference/clibrary/cstdio/printf.html (patrz ramka ".precision")
C++: http://www.cplusplus.com/reference/iostream/manipulators/setprecision.html (calosc)
co pokazuje ze mozna floata bezposrednio wepchnac na wyjscie i uzyskac dana precyzje automatycznie

edit: ups. oczywiscie nie przy ShowMessage.. moje niedoczytanie pierwszego posta :)

0

quetzalcoatl a o czym ja pisałem :P. Dokładnie pisałem o przypadku, kiedy trzeba wywalić parametr będący koniecznie string/char*/AnsiString i inne. O printf nie musisz mi wspominać :). Jakoś z przyzwyczajenia korzystam jedynie z printf i scanf (spadek po olimpiadach i konkursach gdzie nie zalecano cin i cout). Dodatkowo można posłużyć się sscanf i sprintf, które są niezmiernie przydatne w wielu prostych przypadkach no i dodatkowo działają w czystym C w którym zdarza mi się pisać.

A ShowMessage właśnie pobiera stringa i to stąd moja odpowiedź...

Poza tym powiem Ci, że ja od lat jak tworzę programy dla kogoś to nie wczytuję jako liczby, a jako tekst, bo idiotoodporność jest dla mnie ważna. Jak napisałem raz kalkulator w konsoli liczący skomplikowane wyrażenia (dokłądnie chodziło o liczenia numeryczne całki oznaczonej z dowolnego wzoru) to tak to napisalem, że na ponad 2000 linii 1500 stanowiła idiotoodporność :). Ale programu nie dało się wywalić i nie dało się wpisać wyrażenia z brakującym nawiastem itd itd bo użytkownik był o tym informowany na bieŻąco (Boże, widzisz takie błędy i nie grzmisz). Ale to tak na marginesie.

0
RR napisał(a)

quetzalcoatl a o czym ja pisałem :P. (..) A ShowMessage właśnie pobiera stringa i to stąd moja odpowiedź...

no wiec wlasnie to zauwazylem i stad w moim poprzednim poscie jest dopisek: ooops:)

RR napisał(a)

Poza tym powiem Ci, że ja od lat jak tworzę programy dla kogoś to nie wczytuję jako liczby, a jako tekst, bo idiotoodporność jest dla mnie ważna. Jak napisałem raz kalkulator w konsoli liczący skomplikowane wyrażenia (...)

alez to co mowie tego nie neguje.. ja tylko mowie ze jesli w ogole masz mozliwosc czytania jako liczbe, to jak to zrobisz jest w zasadzie to bezznaczenia i czytajac jako liczby mozesz dokonywac tak samo dobrych testow poprawnosci odczytu jak bys czytal jako znaki :) i tak samo z wypisywaniem. to ze czasem nie ma takiej mozliwosci (np. w owym showmessage) - to z tym co mowie nie koliduje. mam na mysli ze jak ma sie wybor pomiedzy czytaniem/pisaniem tekstu a liczby, to po co sobie utrudniac. scanf zwraca ilosc trafien, nie problem wykryc ze ktos podal nie-liczbe. cin wpada w stan fail, wiec tez nie problem. oczywiscie -- wszystko pozostale, jak w przykladzie tego kalkulatora, czyli operatory matematyczne, nawiasy, literaly itp trzeba juz czytac jako ciagi. z tego powodu, zeby juz nie rozszczepiac czytania wejscia na dwa przypadki wszystko traktuje sie tak samo i najpierw czyta do ciagu znakow a potem analizuje co to jest -- bo nie wiadomo czy tu sie pojawi liczba, czy literal czy nawias itp. natomiast jak wiadomo ze ma sie pojawic liczba.. to czytanie "na okolo" nie ma sensu

0

no wiec wlasnie to zauwazylem i stad w moim poprzednim poscie jest dopisek: ooops:)

Wiem :) Widziałem. Ale to co napisałem temu nie przeczy :).

alez to co mowie tego nie neguje..

To też wiem. Mój opis/uwaga była jedynie moim własnym doświadczeniem w tej sprawie. A wczytuje i ręcznie sprawdzam, bo warto wiedzieć co jest błędem. Można wtedy kogoś o tym poinfromować.

pozdr

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