?

Log in

No account? Create an account
Машинная арифметика - In 3.14 we trust [entries|archive|friends|userinfo]
BrotherFlame

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Машинная арифметика [Feb. 4th, 2010|12:41 pm]
BrotherFlame
Не программерам не читать. Реально не интересно.

Итак, вопрос. Я думаю, что к Жене, потому что из остальных знакомых 6 прогаммеров на него не ответил никто даже с википедией. Т.е. никто не понимает машинную арифметику. И мне стало интересно, потому что я видимо тоже не понимаю.

Есть Double. 64битный. Это в яве. В С++ это называется long double вроде.
И работают они с ним одинаково, согласно IEEE754.

Как в Double представляется число 2 (по битам)?

Алгоритм перевода: http://www.sgu.ru/prcnit/teach/3.php
В принципе, везде одинаково пишут.
В скобочках указываю систему счисления (2) -- двоичная, (10) --
десятичная. ^ -- степень. 10^2 -- 10 во второй.
Че делаем по нему:
1) 2 = 2.0 (10)
2) 2.0 == 10.000...0 (2)
3) Нормализуем: 10.00000...0 = 1.000000...000*10^1
4) Берем смещение экспоненты, оно равно: 1023 для 64битного дабла.
Порядок у нас = 1. Значит смещеннный порядок: 1023+1 = 1024 (10).
1024(10) = 1000000000 (2) 11 знаков, ед. и 10 нулей.
первый разряд это знак. у нас там должен быть 0.
11 следующих -- экспонента == 10000000000 (2)
И остальные 52 -- мантисса. Т.к. мантисса всегда начинается с 1, машина это уже знает и отбрасывает ее, т.е. должно получится в итоге:
01000....000
Однако
Double x = 2;
System.out.println("x(2) == " + Double.toLongBits(x));
выдает:
10000....000.
Почему?
LinkReply

Comments:
(Deleted comment)
[User Picture]From: brotherflame
2010-02-04 01:34 pm (UTC)
Да есть в додиезе че-то подобное, это же копия явы.

короче, смысл представит даблу как она выглядит по битам.

Кстати, я понял в чем мой косяк был. Я правильно все посчитал, но не понял этого сразу. Просто toLongBits отбросил первый ноль, который знаковый.
(Reply) (Parent) (Thread)
(Deleted comment)
[User Picture]From: brotherflame
2010-02-04 08:02 pm (UTC)
Меня осенило после того, как я получил первый каммент :)
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-02-04 07:41 pm (UTC)

Юджин

:)

Хитрая ошибка ;) На самом деле, Шур, я про IEEE 754 смутно помню со скучных лекций в институте, НО:

1. Я посмотрел описание метода doubleToLongBits. Он возвращает long. А любое число, приведенное к строке теряет ведущие ноли :))) Консоль приводит к строке :)
2. Вот тебе загадка :) Ты пишешь, что метод отбросил первый ноль. Как ты считаешь, а сколько первых нолей отбросило приведение типов? ;)
(Reply) (Parent) (Thread)
[User Picture]From: brotherflame
2010-02-04 08:00 pm (UTC)

Re: Юджин

На второй вопрос ответ можно посмотреть в спеках типов.
long = 64 бита.
double = 64 бита.
При преобразовании потеряно 0 бит. Я это первым делом проверил, а вот банальность со сторокой не учел :)

Кстати, вот собсно оригинальный вопрос откуда я заинтересовался даблами.
Какие особенности есть у Double.NaN?
Это число, у которого 1 в знаковом разряде и 11 ед. в экспоненте.
Я предполагаю, что оно так сделано потому, что такое число при умножении по правилам машинной арифметики на любое другое число даст тот же самый Double.NaN. Но вот как реализован тот факт, что
Double.NaN < Double.POSITIVE_INFINITY == false
и
Double.NaN > Double.NEGATIVE_INFINITY == false
я пока не понял. То же самое будет если их проверить на равенство.
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-02-04 08:14 pm (UTC)

Юджин

Шур, я кретин :) Все верно - один ведущий ноль :)))
(Reply) (Parent) (Thread)