Для правильного использования математики с расширенной точностью необходимо, чтобы язык поддерживал тип, который может использоваться для хранения результатов промежуточных вычислений, и мог быть заменен на выражения, дающие эти результаты.Таким образом, с учетом:
void print_dist_squared(double x1, double y1, double x2, double y2)
{
printf("%12.6f", (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
должен быть какой-то тип, который можно использовать для захвата и замены общих подвыражений x2-x1
и y2-y1
, позволяя переписать код как:
void print_dist_squared(double x1, double y1, double x2, double y2)
{
some_type dx = x2-x1;
some_type dy = y2-y1;
printf("%12.6f", dx*dx + dy*dy);
}
без изменения семантики программы.К сожалению, ANSI C не смог указать какой-либо тип, который мог бы использоваться для some_type
на платформах, которые выполняют вычисления с повышенной точностью, и стало гораздо более распространенным обвинять Intel в существовании типов с расширенной точностью, чем обвинять в неудачной поддержке ANSI.
Фактически, типы с расширенной точностью имеют такое же значение на платформах без модулей с плавающей запятой, как и на процессорах x87, поскольку на таких процессорах вычисления, подобные x + y + z, влекут за собой следующие шаги:
- Распакуйте мантиссу, экспоненту и, возможно, знак x в отдельные регистры (экспонента и знак часто могут "двухъярусными")
- Аналогично распакуйте y.
- Сдвиньте вправо мантиссу значения с меньшим показателем степени, если он есть, а затем сложите или вычтите значения.
- В случае, если x и y имели разные знаки, сдвигайте мантиссу влево до тех пор, пока самый левый бит не станет1 и отрегулируйте показатель степени соответствующим образом.
- Упакуйте показатель степени и мантиссу обратно в двойной формат.
- Распаковать этот временный результат.
- Распаковать z.
- Сместить вправо мантиссу значения с меньшим показателем степени, если он есть, а затем сложить или вычесть значения.
- В случае, если предыдущий результат и z имели разные знаки, сдвиньте мантиссу влево до крайнего левого бита, равного 1, и соответствующим образом скорректируйте показатель степени.
- Упакуйте показатель степени и мантиссу обратно в двойной формат.
Использование типа с повышенной точностью позволит исключить шаги 4, 5 и 6.Поскольку 53-битная мантисса слишком велика, чтобы поместиться менее чем в четыре 16-битных регистра или в два 32-битных регистра, выполнение сложения с помощью 64-битной мантиссы не медленнее, чем при использовании 53-битной мантиссы, поэтому использованиематематика с расширенной точностью предлагает более быстрые вычисления без недостатков в языке, который поддерживает правильный тип для хранения временных результатов .Нет оснований обвинять Intel в предоставлении FPU, который мог бы выполнять математические вычисления с плавающей запятой таким способом, который был и самым эффективным методом на чипах без FPU.