LINUX.ORG.RU

[JavaScript][Мазила] 1.2 * 3 = ?

 


2

1

Отлаживал один проект, случайно наткнулся на баг(?).

<!DOCTYPE html>
<html>
	<head>
		<title>WTF?!</title>
	</head>
	
	<body>
		<script type="text/javascript">
			<!--
			alert(1.2*3);
			//-->
		</script>
	</body>
</html>

Готовая страница: http://ompldr.org/vYXM4NQ
Результат: http://ompldr.org/vYXM3eg

Как такое вообще возможно?
P.S. Проявляется в FF 3.6.23, в других браузерах того же семейства ещё не проверял.

☆☆

Последнее исправление: wintrolls (всего исправлений: 2)
Ответ на: комментарий от Eddy_Em

В общем, для начала надо эти числа преобразовать в строки.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от KRoN73

Обычно людям нужно вывести значимые цифры числа.

Для этого есть sprintf, «%g» и подобные штуки. Ах да, забыл, в убогом js ничего этого нет.

baverman ★★★
()
Ответ на: комментарий от baverman

>Для этого есть sprintf, «%g» и подобные штуки

О, да. У вас нет вкусного борща? У нас для Вас есть хорошие новости: свёкла, капуста, вода! :D

Ах да, забыл, в убогом js ничего этого нет.

Речь не о JS, а о порицании GIGO. А так — можно с таким же успехом сказать, что это в убогом Си нету неформатированного, human-readable вывода :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Причем тут GIGO? Давай представим, что js у нас лапка (как бы):

js> var a = 1.2*3
js> var b = 3.6
js> a
3.6
js> b
3.6
js> a == b
false

Опаньки и тысячи багрепортов засыпают бедных разработчиков.

Кстати, в нормальных языках операции приведения к строке и приведения к строковому представлению — разные. Поэтому можно легко писать «print 1.2*3», и в тоже время знать, что конкретно скрывается под красивой строковой личиной.

baverman ★★★
()
Ответ на: комментарий от baverman

>Причем тут GIGO?

При том. Последние разряды — мусор. Если ты его отображаешь, значит — GIGO.

Давай представим, что js у нас лапка

Ты муть какую-то прислал. Плавучку через == не сравнивают никогда. Если, конечно, программист не неэрудированный школьник. Или в институтах на младших курсах уже не изучают как нужно сравнивать числа с плавающей точкой?

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Если ты его отображаешь, значит — GIGO.

Nope. Это не мусор. Нарушается инвариант eval(repr(obj)) == obj. То есть, корректный сериализатор/десиализатор средствами языка уже сделать невозможно.

baverman ★★★
()
Ответ на: комментарий от baverman

>Nope. Это не мусор

Мусор. Незначащие цифры — мусор.

Нарушается инвариант eval(repr(obj)) == obj

OMFG. Ещё раз, для школьников. Числа с плавающей точкой нельзя сравнивать через операцию равенства.

В общем случае 1/3*3 != 3. Со всеми вытекающми.

То есть, корректный сериализатор/десиализатор средствами языка уже сделать невозможно.

При чём тут сериализация?

http://www.google.ru/search?num=100&hl=ru&newwindow=1&client=oper...

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Плавучку через == не сравнивают никогда

4.2: в CUDA только так и сравнивают: (a != 0.f) (т.к. константы вроде FLT_EPSILON там нет)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от wintrolls

То, что для тебя число выглядит как десятичная запись с одной цифрой после запятой, не значит, что оно этой записью является. Особенно когда его как-то изменяют. Вот как это число будет представлено твоим любимым транслятором — фактически и есть это число.

Xenesz ★★★★
()
Ответ на: комментарий от PolarFox

Этот баг есть в куче языков от C до Python.

Проверил.

виндокалькулятор - 3.6

PythonMath (питон на айпаде) - 3.6

iLuaBox (луа на айпаде) - 3.6

PrgCalc (эмулятор Б3-34 на айпаде) - 3.6

Gambit REPL (схема на айпаде) - таки баг.

Приду домой, проверю ещё.

Miguel ★★★★★
()
Ответ на: комментарий от KRoN73

>В общем случае 1/3*3 != 3.

Я тебе один умный вещь скажу, оно и в обычной математике тоже не равно.

dn2010 ★★★★★
()
Ответ на: комментарий от Miguel

>Приду домой, проверю ещё.

Тут всё зависит от того, к чему ближе разработчик языка — к науке и математике или к железкам :)

Понятно, что первые стараются создать язык более практичный, второй — более полно отражающий потроха.

Кстати, и в Б3-34, и в МК-85 все расчёты велись с лишними знаками. У Б3-34 с одним лишним знакому, на МК-85 — с двумя. Т.е. у последнего при 14 цифрах мантиссы показывалось только 12.

Кстати, там и при сравнении на тождество плавающих чисел автоматически эпсилон учитывался. Поэтому такое сравнение — работало.

Вообще, в современных языках, где эпсилон явно не оговаривается, за сравнение на тождество плавающих чисел давно пора исключение бросать :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Ок. Ты похоже совсем зациклился на этом несчастном эпсилоне. Попробуем вернутся к примеру с js. Тебе не кажется странным, что две переменные (полученные от куда-то, неважно) при выводе равны, а при сравнении не равны? Причем узнать истинное значение никак нельзя!

Как должен поступить средний программист на js? Заметь, скорее всего, численных методов он ни в каком виде не изучал, поэтому про двоичное представление плавающих ничегошеньки не знает. Сейчас всё просто, он делает alert и видит что они разные — всё в порядке, действительно не равны.

baverman ★★★
()
Ответ на: комментарий от baverman

>Как должен поступить средний программист на js?

Не стрелять себе в ногу и работать с безопасными данными.

У криворучек всегда что-нибудь работает не так, не только float'ы.

Yasenfire
()
Ответ на: комментарий от baverman

>Тебе не кажется странным, что две переменные (полученные от куда-то, неважно) при выводе равны, а при сравнении не равны?

Сравни в Java по тождеству два Integer(120). Потом — два Integer(130). Удивись. Думай.

Как должен поступить средний программист на js?

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

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Сравни в Java по тождеству

Передернул, так передернул. В жабке у меня есть возможность узнать *причину* такого поведения.

baverman ★★★
()
Ответ на: комментарий от baverman

>В жабке у меня есть возможность узнать *причину* такого поведения.

Если ты хоть немного учил теорию программирования, то сабжевое поведение тебе даже изучать не придётся — ты его заранее будешь знать.

KRoN73 ★★★★★
()
Ответ на: комментарий от baverman

>Видимо, разработчики js думают иначе, и слава богу.

Какие конкретно? Посмотри внимательно на эту тему.

Они уж точно поумнее тебя.

Не факт, не факт…

KRoN73 ★★★★★
()
Ответ на: комментарий от wintrolls

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

Alve ★★★★★
()
Ответ на: комментарий от Alve

Да ладно, во всех нормальных языках с этим уже давно всё в порядке.

wintrolls ☆☆
() автор топика
Ответ на: комментарий от wxw

У меня есть браузер, не умеющий JS. А показывать код скрипта вместо его выполнения это очень дурной тон. Лучше скрыть.

x3al ★★★★★
()
Ответ на: комментарий от x3al

> У меня есть браузер, не умеющий JS. А показывать код скрипта вместо его выполнения это очень дурной тон

Вот и я о том же :)

wxw ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.