24.04.2011, 00:01
|
Новичок на форуме
|
|
Регистрация: 24.05.2010
Сообщений: 5
|
|
что за бред выдает 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) при умножении их на сто, оказалось следующее :
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.
Кто что знает по этому поводу? Спасибо.
|
|
24.04.2011, 00:08
|
|
Матрос
|
|
Регистрация: 04.04.2008
Сообщений: 6,246
|
|
вот и выросло еще одно поколение, которое не знает ничего о числах с плавающей запятой, и как они представляются в компьютере
|
|
24.04.2011, 00:16
|
sinistral
|
|
Регистрация: 28.03.2011
Сообщений: 5,418
|
|
Здравствуйте!
Судя по вашему сообщению, вы ну совсем не знаете javascript.
Освойте основы языка и вопрос отпадет сам, полностью или частично.
А с чем не справитесь - поможем.
На сайте javascript можно начать изучать с учебника, раздел Основы javascript.
Возможно, вам также понадобится HTML - учебник есть, например, здесь: http://ru.html.net/tutorials/html/
Задавайте конкретные вопросы по ходу дела.
|
|
24.04.2011, 00:41
|
Новичок на форуме
|
|
Регистрация: 24.05.2010
Сообщений: 5
|
|
Gvozd причем тут поколение??? И при чем тут представления чисел в компьютере?
Если эти примеры набрать в калькуляторе Winodws - все результаты множения/деления будут правильными.
Если это набрать на серверных языках программирования, например PHP или PERL, тоже все правильно (о, заметьте, они тоже исполняются на компьютере!!).
melky, знаю JavaScript отлично! А также AJAX, jQuery, PHP, PERL и т.д.(не говоря уже о HTML(5), и CSS)
Если Вы все такие умные в этом вопросе, то могли бы дать ответ, по поводу "своего знания о числах с плавающей запятой".
"Задавайте конкретные вопросы по ходу дела."
Вот Вам конкретный вопрос:
Почему при умножении числа 0,58 на 100 в среде JavaScript, в итоге получается число 57.99999999999999 ????
|
|
24.04.2011, 01:07
|
|
Люмус, Емаксос Developer!
|
|
Регистрация: 06.05.2010
Сообщений: 677
|
|
Как не странно в компьютере все данные хранятся как набор из 1 и 0, в том числе и числа. И если взять число 1.1 и перевести в двоичную систему исчисления то оно превратится в 1.100110011001100110011001100110011001100110011001 1010b * 2^(-4) это очень длинное число. Компьютер не может его хранить целиком так как оно займет всю оперативную память, поэтому он обрезает подобные числа. Ну и естественно если теперь взять это обрезанное число и произвести с ним мат. операцию то на выходе мы получим немного не то что ожидали.
Последний раз редактировалось Magneto, 16.12.2011 в 18:10.
|
|
24.04.2011, 01:08
|
Профессор
|
|
Регистрация: 14.12.2009
Сообщений: 155
|
|
Цитата:
|
при чем тут представления чисел в компьютере?
|
Цитата:
|
Почему при умножении числа 0,58 на 100 в среде JavaScript, в итоге получается число 57.99999999999999 ????
|
Смею заметить, что Вы плохо представляете себе о способах хранения вещественных чисел в памяти компьютера. Не смотря на то, что встречавшиеся Вам компьютерные программы умеет выполнять сложные вычисления с высокой точностью, все это только видимость.
Дело в том, что все вещественные числа хранятся в ячейках памяти определенного размера, определяемого количеством байт. А Вы знаете, что каждый байт это 8 битная ячейка. То есть под каждое число отводится определенный набор битов. Так как количество битов конечно, то и количество хранимых чисел ограничено. Следовательно, не все вещественные числа могут быть воспроизведены в памяти компьютера.
А теперь поговорим об "умных" программах, которые вычисляют правильно. Независимо от языка программирования все операции с вещественными числами выполняет процессор по определенному алгоритму и хранит их в памяти. То есть ограничения накладывает не язык, а сама машина. А то что Вы получаете верный результат в программе "Калькулятор", это всего навсего, программисты позаботились о выводе. То есть, "Калькуляторе" тоже посчитал 0,58 * 100 = 57.99999999999999, но перед тем как показать результат, округлил его до 58.
Последний раз редактировалось with-love-from-siberia, 24.04.2011 в 01:11.
|
|
24.04.2011, 01:15
|
|
Матрос
|
|
Регистрация: 04.04.2008
Сообщений: 6,246
|
|
Сообщение от maasja
|
причем тут поколение???
|
не при чем на самом деле.
от момента создания первого действующего компьютера, и до сего момента существуют люди задающие такие вопросы как вы.
и разумеется они присутствуют в каждом поколении пока что.
Сообщение от maasja
|
И при чем тут представления чисел в компьютере?
|
самое что ни есть прямое отношение к вашему вопросу.
http://xpoint.ru/know-how/Articles/F...mbers?comments
Сообщение от maasja
|
Если это набрать на серверных языках программирования, например PHP или PERL, тоже все правильно (о, заметьте, они тоже исполняются на компьютере!!).
|
да неужели?!))))
вы шутите
сейчас не найду(возможно из-за того что такое ... удаляют с хабра) статью на хабре, где кто-то нашел такой же баг в PHP
|
|
24.04.2011, 01:21
|
|
Матрос
|
|
Регистрация: 04.04.2008
Сообщений: 6,246
|
|
Сообщение от with-love-from-siberia
|
То есть, "Калькуляторе" тоже посчитал 0,58 * 100 = 57.99999999999999, но перед тем как показать результат, округлил его до 58.
|
если вспомнить о библиотеках длинных вычислений, то окажется что вы не правы.
полагаю, что именно библиотека длинной арифметики используется в калькуляторе.
но, длинная арифметика обычно нафиг не нужна
|
|
24.04.2011, 01:25
|
Профессор
|
|
Регистрация: 14.12.2009
Сообщений: 155
|
|
Сообщение от Gvozd
|
библиотека длинной арифметики
|
Возможно, но мы не можем это ни подтвердить, ни опровергнуть. Если только мы не знаем этого наверняка.
|
|
24.04.2011, 09:45
|
Особый гость
|
|
Регистрация: 02.04.2010
Сообщений: 4,260
|
|
Сообщение от 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. Начните с простого учебника по парадигме программирования.
Последний раз редактировалось monolithed, 24.04.2011 в 10:09.
|
|
|
|