Я следую алгоритмам, предоставленным в этой статье Эндрю Таллом , описывающим алгоритмы для выполнения математических операций с использованием типа данных df64, пары 32-битных чисел с плавающей запятой, используемой для имитации точности 64 -битное число с плавающей запятой. Однако, как представляется, существуют некоторые несоответствия (ошибки?) В том, как они написали свои функции деления и квадрата Root.
Вот как в статье написана функция деления:
float2 df64_div(float2 B, float2 A) {
float xn = 1.0f / A.x;
float yn = B.x * xn;
float diff = (df64_diff(B, df64_mult(A, yn))).x;
float2 prod = twoProd(xn, diffTerm);
return df64_add(yn, prodTerm);
}
Язык, используемый для написания этого кода, кажется, Cg, для справки, хотя вы должны иметь возможность интерпретировать этот код в C ++, если вы обрабатываете float2
, как будто это просто псевдоним для struct float2{float x, y;};
, с некоторым дополнительным синтаксисом для поддержки арифметических c операций непосредственно над типом.
Для справки, это заголовки функций, используемых в этом коде:
float2 df64_add(float2 a, float2 b);
float2 df64_mult(float2 a, float2 b);
float2 df64_diff(/*Not provided...*/);
float2 twoProd(float a, float b);
Таким образом, сразу несколько проблем выделяются:
diffTerm
и prodTerm
никогда не определяются. Есть две переменные, diff
и prod
, которые определены , но нет уверенности, что это термины, которые были предназначены в этом коде. - Нет объявления
df64_diff
при условии. Предположительно это предназначено для поддержки вычитания; но опять же, это не ясно. df64_mult
- это функция, которая не принимает 32-битное значение с плавающей точкой в качестве аргумента; он поддерживает только две пары 32-битных чисел с плавающей точкой в качестве аргументов. Непонятно, каким образом документ ожидает, что этот вызов функции скомпилирует - То же самое и для
df64_add
, который также принимает в качестве аргументов только пары 32-битных чисел с плавающей точкой, но здесь он вызывается только с первым аргументом, являющимся один 32-разрядный тип с плавающей точкой.
Я делаю обоснованное предположение, что это правильная реализация этого кода, но поскольку даже правильная реализация этой функции имеет неизбежные ошибки в вычислениях, я могу Не скажу, если это правильно, даже если он дает значения, которые «кажутся» правильными:
float2 df64_div(float2 B, float2 A) {
float xn = 1.0f / A.x;
float yn = B.x * xn;
float diff = (df64_diff(B, df64_mult(A, float2(yn, 0)))).x;
float2 prod = twoProd(xn, diff);
return df64_add(float2(yn, 0), prod);
}
float2 df64_diff(float2 a, float2 b) {
return df64_add(a, float2(-b.x, -b.y));
}
Поэтому мой вопрос заключается в следующем: точна ли письменная реализация этого алгоритма, как видно из статьи (потому что это зависит о поведении языка Cg, о котором я не знаю?) или нет? И независимо от того, является ли моя интерполяция этого кода правильной реализацией алгоритма деления, описанного в статье?
Примечание: мой целевой язык - C ++, поэтому, хотя различия между языками (для этого вида алгоритма) второстепенный, мой код написан на C ++, и я ищу правильность для языка C ++.