Почему ошибка округления не считается багом в ЯП?

Я думаю, всем ясно, о чём я говорю. Только что я узнал, что мы, джаваскриптеры, не одиноки - эта ошибка есть ещё и в Ruby, и в Python, и ещё чёрт знает в скольки языках. Больше интерпретаторов на своей машине я не нашёл, поэтому переходим к компиляторам:

C (здесь и далее только значимая часть кода):

float a = 0.1+0.2;
printf("%.20f", a); //так выводится float с точностью 20 знаков после запятой
//0.30000001192092896000

Немного иначе записанный С даёт точность чуть лучше (знакомый результат, не так ли?):

printf("%.20f", 0.1+0.2);
//0.30000000000000004000

На этом моменте можно подумать, что это фундаментальная ошибка компилятора, процессора, а то и всей вселенной, но попробуем-ка C++:

float a = 0.1+0.2;
cout << a;
//0.3

C++ считает без ошибок. C++ считает без ошибок!! Почему JS, написанный на C++ (все известные мне реализации) считает с ошибками? Почему проходят годы, выходят новые версии языков, а на эту ошибку никто не обращает внимание? Как объяснить, скажем, ребёнку, что нельзя просто так взять и сложить два дробных числа?

http://stackoverflow.com/questions/588004/is-floating-point-math-broken — думаю здесь обсудили все что можно по этой теме.

Вот достаточно подробная в тоже время понятная статья.
http://www.2ality.com/2012/04/number-encoding.html

1 лайк

Много нового только что узнал о числах с точки зрения процессора из этой статьи: http://habrahabr.ru/company/xakep/blog/257897/. Там лежат ответы почти на все волновавшие меня вопросы по этой теме. Вопрос: как получить бинарное представление значения число-не-число (бесподобный перевод термина NaN) и плюс/минус бесконечностей? Бежать раскапывать сорцы node.js? Или, может быть, мне поможет магия битовых сдвигов?

1 лайк