Я пытаюсь преобразовать значение двойной точности с плавающей запятой x
в десятичное с 12 (правильно округленными) значащими цифрами. Я предполагаю, что x
находится между 10 ^ 110 и 10 ^ 111, так что его десятичное представление будет иметь вид x.xxxxxxxxxxxE110
. И, просто для удовольствия, я пытаюсь использовать только арифметику с плавающей запятой.
Я пришел к псевдокоду ниже, где все операции являются операциями с двойной точностью. Обозначение 1e98
- для ближайшего к математике 10 ^ 98, а 1e98_2
является двойным, ближайшим к результату математическое вычитание 10 ^ 98- 1e98
. Обозначение fmadd(X * Y + Z)
относится к операции с объединенным многократным добавлением с операндами x
, Y
, Z
.
y = x * 2^-1074; // exact
q = y / 1e98; // q is denormal and the significand of q interpreted
// as an integer is our candidate for the 12 decimal
// digits of x
r = fmadd(q * 1e98 - y); // close to 1e98 * (error made during the division)
// If 1e98_2 >= 0, we divided by a number that was smaller than we wished
// The correct answer may be q or q+1.
if (r and 1e98_2 have opposite signs)
{
return the significand of q;
}
s = copysign(2^-1074, r);
r1 = abs(r);
r2 = abs(1e98_2);
h = 1e98 * 0.5 * 2^-1074;
Set rounding mode to downwards
r3 = fmadd(r2 * q + r1);
if (r3 < h)
{
return the significand of q;
}
else
{
return significand of (q + s)
}
Я извиняюсь за путаницу, которая пронизывает вышеупомянутый псевдокод, но мне пока это не совсем понятно, поэтому следующие вопросы:
-
Работает ли первый fmadd по назначению (для вычисления 1e98 * (ошибка, сделанная во время деления))?
-
Знаки. Я не могу убедить себя, что они правы. Но я не могу убедить себя, что они ошибаются.
-
Любая идея, возможно, аргументы о частоте, с которой этот алгоритм может произвести неверный результат?
-
Если это вообще работает, есть ли вероятность, что алгоритм продолжит работу, если "q = y/1e98" изменено на "q = y * 1e-98" (оставив все остальные инструкции одинаковыми )?
Я не тестировал этот алгоритм. У меня нет компьютера с инструкцией fmadd, хотя я надеюсь найти его, чтобы выполнить выше.