Konwersja z double do float w Javie

Jeśli pracuję z double i zamieniam ją na float, Jak to dokładnie działa? Czy wartość jest obcięta, aby pasowała do pływaka? A może wartość jest zaokrąglana inaczej? Przepraszam, jeśli brzmi to trochę zaradczo, ale staram się zrozumieć koncepcję Konwersji float i double.

Author: Franklin, 2012-04-09

2 answers

Z specyfikacja języka Java , sekcja 5.1.3:

Zawężenie prymitywnej konwersji z podwójnego na float jest regulowane przez reguły zaokrąglania IEEE 754 (§4.2.4). Ta konwersja może stracić precyzję, ale także stracić zakres, w wyniku czego float zero z niezerowej dwójki i float nieskończoność z skończonej dwójki. Podwójne NaN jest konwertowane na zmiennoprzecinkową NaN, a Podwójna nieskończoność jest konwertowana na tę samą zmiennoprzecinkową nieskończoność.

I sekcja 4.2.4 mówi:

Język programowania Java wymaga, aby arytmetyka zmiennoprzecinkowa zachowywała się tak, jakby każdy operator zmiennoprzecinkowy zaokrąglał swój wynik zmiennoprzecinkowy do dokładności wyniku. Inexact results must be rounded to the representable value near to the infinitely precise result; if the two nearest representable values are equally near, the one with its least significant bit zero is chosed. Jest to domyślny tryb zaokrąglania standardu IEEE 754 znany jako / align = "left" /

 19
Author: Oliver Charlesworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-09 14:55:52

Sugerowałbym, że typy zmiennoprzecinkowe są najbardziej użyteczne jako reprezentujące zakresy wartości. Powodem, dla którego 0.1 F wyświetla się jako 0.1, a nie jako 0.100000001490116119384765625, jest to, że w rzeczywistości reprezentuje zakres liczb od 13421772.5/134217728 do 13421773.5/134217728 (tj. od 134217728). 0.0999999977648258209228515625 do 0.1000000052154064178466796875); nie ma sensu dodawać dodatkowych cyfr wskazujących, że liczba jest większa niż 0.100, gdy może być mniejsza, ani używać ciąg dziewiątek oznaczający liczbę jest mniejszy niż 0.100, gdy może być większy.

Rzucenie podwójnego na zmiennoprzecinkowy wybierze zmiennoprzecinkowy, którego zakres wartości Zawiera zakres podwajania reprezentowany przez podwajanie. Zauważ, że podczas gdy operacja ta jest nieodwracalna, wynik operacji będzie na ogół arytmetycznie poprawny; jedynym czasem nie byłoby 100% arytmetycznie poprawne byłoby, gdyby ktoś rzucał do pływaka podwójnego, którego zakres był dokładnie wyśrodkowany na granica między dwoma pływakami. W takiej sytuacji system wybierałby float po jednej lub drugiej stronie zakresu double ' a; jeśli double faktycznie reprezentowałby liczbę po niewłaściwej stronie zakresu, wynikająca z tego konwersja byłaby nieco niedokładna.

W praktyce mała nieprecyzyjność, o której mowa powyżej, prawie nigdy nie ma znaczenia, ponieważ "zakres wartości" reprezentowany przez typ zmiennoprzecinkowy jest w praktyce nieco większy niż wskazany powyżej. Wykonywanie obliczeń (takie jak dodawanie) na dwóch liczbach, które mają pewną ilość niepewności, da wynik z większą niepewnością, ale system nie będzie śledzić, ile niepewności istnieje. Niemniej jednak, o ile nie wykonuje się dziesiątek operacji na platformie lub tysięcy operacji na podwójnym, ilość niepewności będzie zwykle na tyle mała, że nie będzie się martwić.

Ważne jest, aby pamiętać, że rzucanie pływaka na dublera jest w rzeczywistości znacznie bardziej niebezpieczną operacją niż rzucanie dublera na float, nawet jeśli Java pozwala na to pierwsze bez ostrzeżenia, ale skrzeczy na to drugie. Rzucanie pływaka na dublet powoduje, że system wybiera dublet, którego zakres jest wyśrodkowany wokół środka zakresu pływaka. To prawie zawsze spowoduje wartość, której rzeczywista niepewność jest znacznie większa niż jest to typowe dla liczb podwójnej precyzji. Na przykład, jeśli rzuci się 0.1 f na podwój, wynik podwojenia będzie reprezentował liczbę z zakresu 0.10000000149011611 do 0.10000000149011613, mimo że liczba, którą ma reprezentować (jedna dziesiąta), jest stosunkowo niewielka.

 8
Author: supercat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-31 15:43:50