Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   что за бред выдает javascript?? 0.29 * 100 = 28.999999999999996 (https://javascript.ru/forum/misc/16821-chto-za-bred-vydaet-javascript-0-29-%2A-100-%3D-28-999999999999996-a.html)

maasja 24.04.2011 00:01

что за бред выдает javascript?? 0.29 * 100 = 28.999999999999996
 
Здравствуйте. Сегодня случайно обнаружил что
0.29 * 100 = 28.999999999999996 , на javascript.
Был в шоке, подумал, что за бред, и на чистой html странице, создал скрипт:
var result = "";
for(i=0;i<100;i++){
number = "0."+i;
result+= "0."+ i +" * 100 = " + (parseFloat(number) * 100) + "<br>\r\n";
}
document.body.innerHTML = result;
(это засунуть в тело body, иначе не будет работать/вставляться в DOM, так как он еще не готов).
Из ста перебранных числ (0.01, 0.02, 0.03, 0.04, 0.05, ... 0.98, 0.99) при умножении их на сто, оказалось следующее :lol: :
0.14 * 100 = 14.000000000000002
0.28 * 100 = 28.000000000000004
0.29 * 100 = 28.999999999999996
0.55 * 100 = 55.00000000000001
0.56 * 100 = 56.00000000000001
0.57 * 100 = 56.99999999999999
0.58 * 100 = 57.99999999999999
Что за бред?
С остальными перебранными цифрами, все нормально. Запускал в разных браузерах, даже на разных операционках, все так же! Открыл онлайн калькуляторы (первые ссылки в поисках через гугл), они тоже такое выдают, так как построенные в основном на JavaScript.
Кто что знает по этому поводу? Спасибо.

Gvozd 24.04.2011 00:08

вот и выросло еще одно поколение, которое не знает ничего о числах с плавающей запятой, и как они представляются в компьютере

melky 24.04.2011 00:16

Здравствуйте!

Судя по вашему сообщению, вы ну совсем не знаете javascript.

Освойте основы языка и вопрос отпадет сам, полностью или частично.
А с чем не справитесь - поможем.

На сайте javascript можно начать изучать с учебника, раздел Основы javascript.
Возможно, вам также понадобится HTML - учебник есть, например, здесь: http://ru.html.net/tutorials/html/

Задавайте конкретные вопросы по ходу дела.

maasja 24.04.2011 00:41

Gvozd причем тут поколение??? И при чем тут представления чисел в компьютере?
Если эти примеры набрать в калькуляторе Winodws - все результаты множения/деления будут правильными.
Если это набрать на серверных языках программирования, например PHP или PERL, тоже все правильно (о, заметьте, они тоже исполняются на компьютере!!).
melky, знаю JavaScript отлично! А также AJAX, jQuery, PHP, PERL и т.д.(не говоря уже о HTML(5), и CSS)
Если Вы все такие умные в этом вопросе, то могли бы дать ответ, по поводу "своего знания о числах с плавающей запятой".
"Задавайте конкретные вопросы по ходу дела."
Вот Вам конкретный вопрос:
Почему при умножении числа 0,58 на 100 в среде JavaScript, в итоге получается число 57.99999999999999 ????

Magneto 24.04.2011 01:07

Как не странно в компьютере все данные хранятся как набор из 1 и 0, в том числе и числа. И если взять число 1.1 и перевести в двоичную систему исчисления то оно превратится в 1.100110011001100110011001100110011001100110011001 1010b * 2^(-4) это очень длинное число. Компьютер не может его хранить целиком так как оно займет всю оперативную память, поэтому он обрезает подобные числа. Ну и естественно если теперь взять это обрезанное число и произвести с ним мат. операцию то на выходе мы получим немного не то что ожидали.

with-love-from-siberia 24.04.2011 01:08

Цитата:

при чем тут представления чисел в компьютере?
Цитата:

Почему при умножении числа 0,58 на 100 в среде JavaScript, в итоге получается число 57.99999999999999 ????
Смею заметить, что Вы плохо представляете себе о способах хранения вещественных чисел в памяти компьютера. Не смотря на то, что встречавшиеся Вам компьютерные программы умеет выполнять сложные вычисления с высокой точностью, все это только видимость.

Дело в том, что все вещественные числа хранятся в ячейках памяти определенного размера, определяемого количеством байт. А Вы знаете, что каждый байт это 8 битная ячейка. То есть под каждое число отводится определенный набор битов. Так как количество битов конечно, то и количество хранимых чисел ограничено. Следовательно, не все вещественные числа могут быть воспроизведены в памяти компьютера.

А теперь поговорим об "умных" программах, которые вычисляют правильно. Независимо от языка программирования все операции с вещественными числами выполняет процессор по определенному алгоритму и хранит их в памяти. То есть ограничения накладывает не язык, а сама машина. А то что Вы получаете верный результат в программе "Калькулятор", это всего навсего, программисты позаботились о выводе. То есть, "Калькуляторе" тоже посчитал 0,58 * 100 = 57.99999999999999, но перед тем как показать результат, округлил его до 58.

Gvozd 24.04.2011 01:15

Цитата:

Сообщение от maasja
причем тут поколение???

не при чем на самом деле.
от момента создания первого действующего компьютера, и до сего момента существуют люди задающие такие вопросы как вы.
и разумеется они присутствуют в каждом поколении пока что.
Цитата:

Сообщение от maasja
И при чем тут представления чисел в компьютере?

самое что ни есть прямое отношение к вашему вопросу.
http://xpoint.ru/know-how/Articles/F...mbers?comments
Цитата:

Сообщение от maasja
Если это набрать на серверных языках программирования, например PHP или PERL, тоже все правильно (о, заметьте, они тоже исполняются на компьютере!!).

да неужели?!))))
вы шутите
сейчас не найду(возможно из-за того что такое ... удаляют с хабра) статью на хабре, где кто-то нашел такой же баг в PHP

Gvozd 24.04.2011 01:21

Цитата:

Сообщение от with-love-from-siberia
То есть, "Калькуляторе" тоже посчитал 0,58 * 100 = 57.99999999999999, но перед тем как показать результат, округлил его до 58.

если вспомнить о библиотеках длинных вычислений, то окажется что вы не правы.
полагаю, что именно библиотека длинной арифметики используется в калькуляторе.
но, длинная арифметика обычно нафиг не нужна

with-love-from-siberia 24.04.2011 01:25

Цитата:

Сообщение от Gvozd
библиотека длинной арифметики

Возможно, но мы не можем это ни подтвердить, ни опровергнуть. Если только мы не знаем этого наверняка.

monolithed 24.04.2011 09:45

Цитата:

Сообщение от maasja
знаю JavaScript отлично! А также AJAX, jQuery,

Угу, забыли написать: DOM, Range, Date, Array, Object и.д.
Если в конкретном случае нужен целочисленный результат, то есть еще один [[Class]] Math, до которого, вы видимо не дошли, пока.

alert(['Math.floor: '+Math.floor(0.58 * 100.99999)+'\n',
       'Math.ceil: '+Math.ceil(0.58 * 100.99999)+'\n',
       'Math.round: '+Math.round(0.58 * 100.99999)+'\n',
       'Math.floor/round: '+Math.floor(Math.round(0.58 * 100.99999))+'\n',
       'Math.floor/ceil: '+Math.ceil(Math.round(0.58 * 100.99999))+'\n'
].join(''));

alert(['Math.floor: '+Math.floor(0.58 * 100)+'\n',
       'Math.ceil: '+Math.ceil(0.58 * 100)+'\n',
       'Math.round: '+Math.round(0.58 * 100)+'\n',
       'Math.floor/round: '+Math.floor(Math.round(0.58 * 100))+'\n',
       'Math.floor/ceil: '+Math.ceil(Math.round(0.58 * 100))+'\n'
].join(''));

PS: только не нужно показывать дипломы о знании JS и PHP. Начните с простого учебника по парадигме программирования.


Часовой пояс GMT +3, время: 22:08.