воскресенье, 23 декабря 2012 г.

Сюрпризы уходящего года

Два наиболее поразительных факта о языках программирования, которые автор узнал в уходящем году:

1. Есть такое правило, к которому все привыкли: если в программе записано логическое выражение с and, и первое подвыражение оказалось равно false, то второе не вычисляется. Аналогично с or: если первое подвыражение равно true, второе не вычисляется. Это позволяет удобно записывать вещи вида

if (index < 0 || array[index] == NULL)
  ...
или
if (index >= 0 && array[index] == ptr)
  ...

Это правило действует во всех широко используемых языках программирования: C/C++, Java, C#, Javascript, Python, а также в многочисленных представителях семейств лиспов и смолтоков. И даже в Хаскеле. И даже в PL/SQL. У правила есть название: закорачивание логических связок (short-circuit evaluation). Казалось, оно само собой разумеется, и есть во всех языках.

При столкновении с языком Fortran автора ждал сильный удар. Закорачивание в этом языке не просто не действует, а может действовать или не действовать в зависимости от воли компилятора. Эта неопределённость закреплена в стандарте. При этом, в интеловском компиляторе, например, просто нет ключа, чтобы этим управлять. Программист не может быть уверен, что выполнится лишь одна ветвь; в то же время, он не может быть уверен, что выполнятся обе. Поведение может зависеть от номера версии компилятора и настроек оптимизации.

2. В интеловских процессорах со времени появления FPU была и есть возможность хранить и производить операции с 80-битными числами с плавающей точкой (extended precision). По сравнению с обычными 64-битными (double precision) это 12 дополнительных бит в мантиссе, то есть больше 3-х десятичных значащих цифр. Практически бесплатно с точки зрения памяти и количества тактов процессора. Есть на каждом десктопе и ноутбуке (т.к. везде интел-совместимые процессоры). Очень актуально для научных расчётов. И как вы думаете, сколько языков программирования к 2012 году дают возможность хранить 80-битные переменные?

Два. Первый из них — Си с типом данных «long double», который окончательно закрепился в стандарте C99. MSVC, кстати, не поддерживает этот тип, как и C99 в целом. Но в GCC и Intel C компиляторе всё чётко.

Второй и последний язык с поддержкой 80-битных чисел — это, гхм, Паскаль, с его типом «extended».

Поправка: нет, есть ещё Perl, который, если скомпилирован с нужными настройками (nvtype=long double) оперирует 80-битными числами. И ещё для перла есть библиотека Math::LongDouble.

Ещё поправка: также автор забыл про язык D, в котором изначально есть поддержка 80-битных чисел, и обещается поддержка 128-битных, видимо как только оные появятся в процессорах.

В Фортране, который для научных расчётов использовался очень широко, и до сих пор используется, нет 80-битных чисел. Точнее говоря, есть (тип данных называется REAL*10), но вне стандарта. Поддерживается в gfortran и маргинальных компиляторах. А в самом популярном — интеловском — нет.

Ведётся работа по внедрению 80-битной арифметики в Racket.

4 комментария:

Анонимный комментирует...

http://perldoc.perl.org/functions/pack.html

Long doubles are available only if your system supports
long double values _and_ if Perl has been compiled to
support those. Raises an exception otherwise

Dmitry комментирует...

Да, на перл я забыл посмотреть. Я всегда забываю про перл. В глубине души я мечтаю, что про него забудет весь мир.

Анонимный комментирует...

80-битные плавающие ещё есть в языке D by design (тип real): http://dlang.org/d-floating-point.html

Dmitry комментирует...

Спасибо, добавил в пост.