2010-06-17 12 views

Odpowiedz

44

Ten argument ma zawsze dwie strony - dziesiętne i całkowite. Zwolennicy liczb całkowitych twierdzą, że wartości dziesiętne mogą być niedokładne (podczas konwersji), a implementacja BigDecimal obejmuje błędy, a czasem nawet błędy w segfault.

Dla mojego własnego projektu wziąłem również liczby całkowite, opakowałem je w niestandardowy pojemnik, przeliczając centy na "rzeczywiste" kwoty iz powrotem. Na początku wydawało się to przyjemne, po pewnym czasie stało się naprawdę niewygodne w użyciu - śledzenie, gdy masz do czynienia z centami, kiedy z sformatowanymi ciągami itp.

Potem wróciłem do wartości dziesiętnych - ten sam format cały czas, mogę łatwo przekonwertować Kwota do centów w razie potrzeby, otrzymuję różne algorytmy zaokrągleń po wyjęciu z pudełka. Jestem o wiele bardziej zadowolony z miejsc dziesiętnych.

A problemy z dziesiętnymi nie są dokładne - podczas korzystania z wyszukiwarki można zauważyć, że większość błędów wiąże się z przekształcaniem miejsc po przecinku w znaki pływające :) Jak już wspomniano wcześniej, przepływy nie są dokładne i nigdy nie powinieneś zamień swój dziesiętny na zmiennoprzecinkowy. To najważniejsza rzecz, o której musisz pamiętać w przypadku miejsc dziesiętnych - nie chcesz tracić dokładności przez konwersje. Och, i nigdy nie spotkałem się z żadnymi błędami z ruby ​​1.8.7, 1.8.7 i 1.9.1 podczas intensywnego korzystania z BigDecimal.

+6

+1 "nigdy nie konwertuj swojej wartości dziesiętnej na liczbę zmiennoprzecinkową" ... zdarzają się dziwne rzeczy – tybro0103

10

To zależy.

Jeśli wykonujesz obliczenia cen zakupu, użyj wartości dziesiętnych.
Jeśli wykonujesz matematykę inżynieryjną, użyj float.
Jeśli tylko przechowujesz dane, użyj ciągu znaków.

52
add_column :table, :price, :decimal, :precision => 8, :scale => 2 

Powyższy kod będzie najlepszym wyborem.

+0

Jak to zrobić w linii poleceń? wpisałem "szyny generują rusztowanie Cena produktu: dziesiętna" i utworzyłem kolumnę z: skalą 1. –

+2

W zależności od potrzeb, możesz dodać -> kolumna dodawania: tabela,: waluta,: ciąg,: domyślnie => 'USD ' – Tom

+0

Czy to jest Rails 3? rails g migration Cena AddPriceToYourModel: decimal, następnie przejdź do wygenerowanej migracji i dodaj szczegóły. – Tom

7

Polecam używanie liczb całkowitych do ceny, jeśli to możliwe. Wiele popularnych klejnotów (takich jak ActiveMerchant, Money) zakłada użycie liczb całkowitych i często lepiej jest przechowywać jednostki miary w jednostce podstawowej (np. Centach).

+0

, ale liczby całkowite nie mają wartości 13,25? –

+4

Dlatego opieracie się na centach. Zatem 13,25 USD zostaje zapisany jako 1325 w bazie danych. W widoku formatujesz znak dolara i dziesiętny. – sosborn

+1

O ile oczywiście nie obliczysz ceny czegoś, co wykorzystuje ułamki centa, na przykład ceny gazu. Następnie powinieneś mieć dwa pola - jeden do przechowywania frakcji jako liczby całkowitej i drugi do informowania, ile miejsc dziesiętnych powinien mieć pierwszy numer i ... o, czekaj, że to idiotyzm, po prostu użyj liczby dziesiętnej :) – MikeJ

10

pływaków nie są dokładne:

0.3 - 0.2 - 0.1 
=> -2.77555756156289e-17 

Nie stosować je chyba przechowywać tylko wartości.

Jeśli chcesz wykonać obliczenia, zapisz cenę w centach jako liczbę całkowitą. Możesz łatwo wyświetlać je jako USD za pomocnika.

+2

omg to naprawdę dzieje się. – jturolla

+2

to tylko rzecz prekursorska. Nie ma nic złego w wartości. To -2,7 * 10^-17 jest bardzo bliskie zeru –

Powiązane problemy