• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z liczbą double

+1 głos
59 wizyt
pytanie zadane 8 listopada 2021 w C# przez Pawel1995 Gaduła (3,160 p.)

Cześć, w pracy wyszedł mi problem przy mnożeniu liczby:

double a = 1.11;
double b;

b = a * 10;

Console.WriteLine( "test: " + b);

mogą sobie państwo wyobrazić moje zdziwienie jak wynikiem tego działania było to:

test: 11,100000000000001

I moje pytanie jak zrobić żeby wynikiem tego działania było zwykłe 11,1 ?

2 odpowiedzi

0 głosów
odpowiedź 8 listopada 2021 przez Snejki Stary wyjadacz (14,520 p.)
wybrane 8 listopada 2021 przez Pawel1995
 
Najlepsza
nie wiem, czy to wchodzi w grę, ale w takiej sytuacji zmieniłbym typ double na typ decimal, który poprawnie zapisuje wartości po przecinku
komentarz 8 listopada 2021 przez Pawel1995 Gaduła (3,160 p.)

Tak weszło: 

double a = 1.11;
decimal temp = (decimal)a;
double b;

b = (double)(temp * 10);

Console.WriteLine(DateTime.Now + " test: " + b);

mam to co chciałem. Dziękuje

+1 głos
odpowiedź 8 listopada 2021 przez Oscar Pasjonat (24,050 p.)
Jedyne co możesz zrobić to wyświetlić wynik z odpowiednią precyzją. Pamiętaj, że komputer liczy w układzie binarnym i wartości liczbowe, które mają mała liczbę cyfr w rozwinięciu dziesiętnym (czyli takim "ludzkim") niekoniecznie są takie ładne w rozwinięciu binarnym. O ile 0.5, 0.25 to ładnie rozwijają się binarnie, to 0.1 już nie. Komputer po prostu podał wartość najbliższą poprawnemu wynikowi z tych, które może zapisać binarnie na odpowiedniej liczbie bitów.

Możesz użyć odpowiednich bibliotek liczących w kodzie dziesiętnym (BCD albo po prostu na cyfrach).
komentarz 8 listopada 2021 przez Pawel1995 Gaduła (3,160 p.)

Tyle że to jest uproszczony przykład żeby zobrazować problem. Tak naprawdę 1.11 przychodzi mi z jednego sterownika, danego urządzenia. Jest dokonywana ta stosowna operacja, a następnie tą liczbę, w formacie double ładuje do bazy danych[MongoDB]. 

Tu nie chodzi o wyświetlanie, przy wyświetlaniu wiem że moge zrobić:

b.ToString("F2")

Ale do bazy danych wtedy i tak pójdzie zła wartość.

1
komentarz 8 listopada 2021 przez Oscar Pasjonat (24,050 p.)
To po prostu wpisuj do bazy napis, będzie jak chcesz. Jeśli do bazy zapiszesz jako double to problem pozostanie. Po prostu wartość 0.1 ma okresową reprezentację binarną, podobne jak 1/3 w systemie dziesiętnym. Z kolei 1/3 w systemie trójkowym jest "ładnym ułamkiem" postaci 0.1. Dokładność liczb w komputerze jest skończona. Ale zwykle i tak znacznie lepsza niż to co podają różne urządzenia pomiarowe, ona raczej nie mają nawet 20 bitów dokładności. Każda wartość jaką otrzymujesz ze świata rzeczywistego jest albo całkowita (liczba sztuk) albo i tak przybliżona - każdy wynik pomiarowy. Z takimi danymi rzeczywistymi, często robi się tak, że skaluje się wynik do liczby całkowitej według rozdzielczości urządzenia. Czyli jeśli rozdzielczość jest 1mm to zapisujemy w mm a nie metrach.
komentarz 8 listopada 2021 przez Pawel1995 Gaduła (3,160 p.)
Tak słyszałem o tej praktyce zapisywania wszystkiego jako int, i w drugiej kolumnie tabeli precyzje gdzie dodać przecinek. Zapis jako string nie jest w moim przypadku dostepny, ale dziękuje za podpowiedź. Myślałem że jest jakas opcja żeby przekonać double do poprawnego działania ale trzeba sie bawić z decimal

Podobne pytania

0 głosów
1 odpowiedź 107 wizyt
pytanie zadane 25 stycznia w C i C++ przez Antytalent Początkujący (450 p.)
0 głosów
0 odpowiedzi 45 wizyt
pytanie zadane 19 lutego 2020 w Mikrokontrolery przez Mavimix Dyskutant (8,210 p.)
0 głosów
3 odpowiedzi 517 wizyt
pytanie zadane 26 lipca 2019 w C i C++ przez Jacob7 Użytkownik (540 p.)

87,916 zapytań

136,501 odpowiedzi

304,327 komentarzy

58,290 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...