Многие люди отмечали, что 0x3f800000
является представлением 1.0
. Хотя это верно, это не имеет ничего общего с тем, как работает вычисление. Чтобы понять это, вам нужно знать, как хранятся неотрицательные числа с плавающей запятой. f = (1+m)*2^x
, где 0 <= m < 1
и m
— мантисса, x
— показатель степени. Также обратите внимание, что x
хранится со смещением, поэтому на самом деле в двоичном файле находится x+127
. 32-битное значение состоит из бита знака (который в нашем случае равен нулю), за которым следуют 8 битов экспоненты, хранящей x+127
, и, наконец, 23 бита мантиссы, m
. (См. статью в Википедии).
Примените базовую математику,
sqrt(f) = sqrt((1+m)*2^x)
= sqrt(1+m)*sqrt(2^x)
= sqrt(1+m)*2^(x/2)
Таким образом, в грубом приближении нам нужно уменьшить показатель степени вдвое, но из-за смещения мы не можем просто сделать x/2
, нам нужно (x-127)/2 + 127
. Это 127
, сдвинутое в соответствующую битовую позицию, является магическим 0x3f800000
.
Деление на 2 достигается сдвигом вправо на один бит. Поскольку это работает со всем числом с плавающей запятой, это также имеет побочный эффект и для мантиссы.
Во-первых, предположим, что исходный показатель был четным. Тогда наименее значащий бит, который смещается, равен нулю. Таким образом, мантисса тоже уменьшается вдвое, так что в итоге мы получаем: sqrt(f) = (1+m/2)*2^(x/2)
. Мы получили правильный показатель степени, но мантисса равна (1+m/2)
вместо sqrt(1+m)
. Максимальная относительная ошибка для этого равна (1.5 - sqrt(2))/sqrt(2) ~ 6%
, что происходит, если m
почти 1
, что означает, что f
близко, но меньше нечетной степени 2
. Возьмем, к примеру, f=7.99
. Формула дает нам около 2.998
вместо 2.827
, что действительно имеет ошибку 6%
.
Теперь, если экспонента была нечетной, то младший значащий бит будет 1
, и это при сдвиге в мантисса вызовет увеличение наполовину. Таким образом, мы получаем sqrt(f) = (1.5+m/2)*2^((x-1)/2)
. Максимальная ошибка для этого на самом деле, когда m=0
, и это будет (1.5/sqrt(2)-sqrt(1))/sqrt(1)
, что снова около 6%
. Это происходит для чисел, близких к нечетной степени двойки сверху.
Объединение двух случаев означает, что наихудшая неточность составляет около 6%, если входное значение близко к нечетной степени двойки. Для четных степеней двойки результат точен.
person
Jester
schedule
22.01.2017