2012-04-26 17 views
5

Mam jeden konkretny problem podczas przekształcania wartości double na ciąg znaków przy użyciu sprintf() w systemie UNIX.Formatowanie sprintf o podwójnej wartości

Na przykład mam dwie wartości:

double a = 0.009984354523452; 
double b = 0.01; 

Podczas konwersji używam:

sprintf(somestringvar, "Double value : %.15f \n", a); 
sprintf(diffstringvar, "Double value : %.15f \n", b); 

przekonwertować na sznurku.

Mój problem dotyczy "a", wartość jest drukowana prawidłowo, ale dla wartości "b", 0 są dołączane na końcu. Podaj mi jakiś popularny sposób reprezentowania "a" i "b" jako dokładnych wartości.

+1

Używałbym std :: ostringstream dla tego rodzaju rzeczy. – Robinson

+1

I generalnie nie używaj 'sprintf()', ponieważ może to prowadzić do przepełnienia bufora. Zamiast tego użyj "snprintf()" lub jednej z "bezpiecznych" wersji "Microsoft" w systemie Windows. p.s. Witamy w Stack Overflow! –

+0

Dziękuję za wcześniejsze odpowiedzi. ostringstream nie przyjmuje pełnej precyzji. wartość jest drukowana tylko jako 0,009976. Mogę użyć snprintf(), ale problemem jest prawidłowe drukowanie wartości. – sandy

Odpowiedz

8

Otrzymujesz zero podczas drukowania b, ponieważ poleciłeś printf wydrukować 15 miejsc po przecinku (%.15f) i jest to posłuszne. Aby uzyskać coś "dokładnego", możesz mieć więcej szczęścia dzięki prostemu %g.


[Aktualizacja na podstawie ostatnich komentarzy]

rzeczy naprawdę zależy od tego, co masz na myśli przez „dokładny”. Jeśli dokładnie oznacza to "co użytkownik pierwotnie wprowadził", to podwójne może nie być najlepszym wyborem dla ciebie. Być może przechowywanie wartości jako ciąg, a następnie przekształcenie jej w podwójne, gdy trzeba go użyć w obliczeniach, może działać. Gdy dziesiętna liczba tekstowa jest konwertowana na podwójną, generalnie nie jest już dokładnie taka sama jak tekst. Podczas gdy printf() lub ostream będzie sumiennie drukować dokładnie to, co trzyma podwójna (i czasami ma szczęście, a to, co drukuje, wygląda tak samo jak oryginalna wartość), problem polega na tym, że podwójne nie ma już rzeczywistej wartości początkowej. I w rzeczywistości nigdy tak nie było.

Alternatywnie możesz faworyzować dokładną implementację numeryczną, a nie coś nieodłącznie zbliżonego do liczby podwójnej. Na przykład MySQL ma typy NUMERIC and DECIMAL, które obsługują idealną precyzję kosztem wymuszenia określenia liczby liczb całkowitych i miejsc dziesiętnych z wyprzedzeniem. Nazywa się to arbitrary precision arithmetic i istnieją biblioteki do tego w C/C++.

+0

Dzięki za odpowiedź mogę zrozumieć logiczną część dodawania zeoes. Ale problem występuje w środowisku wykonawczym i powinien odczytać wartości z bazy danych. Wartości mogą być dowolnego rodzaju, jak pokazano powyżej, więc szukam ogólnego sposobu drukowania dokładnych wartości. Próbowałem "% g", nawet jeśli wartość normalizacyjna "a" wynosi 0.009976 – sandy

+0

Dlaczego ludzie wciąż głosują na to? Jeśli masz z tym jakiś problem, wypowiedz się, abym mógł go poprawić lub dostarczyć alternatywną odpowiedź. –

Powiązane problemy