LINUX.ORG.RU
ФорумTalks

А есть ли язык программирования, где нет == для float?


0

0

С руганью за-fail-ил code review фичи, увидев проверку вещественных чисел на равенство(==) и задался вопросом: а изобрело ли человечество такой язык программирования, в котором операторов == и != для вещественных чисел попросту нет.

Да, я знаю, что в сиплюсплюсе через #define и перегрузку это реализуемо, но интересует именно искоробочность решения.

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

★★

Ответ на: комментарий от geek

> asm

тююю...

FCOMI/FCOMIP/ FUCOMI/FUCOMIP — Compare Floating Point Values and
Set EFLAGS

Opcode   Instruction       64-Bit Compat/  Description
                           Mode   Leg Mode
DB F0+i  FCOMI ST, ST(i)   Valid  Valid    Compare ST(0) with ST(i) and set status flags accordingly.
DF F0+i  FCOMIP ST, ST(i)  Valid  Valid    Compare ST(0) with ST(i), set status flags accordingly, and pop register stack.
DB E8+i  FUCOMI ST, ST(i)  Valid  Valid    Compare ST(0) with ST(i), check for ordered values, and set status flags
accordingly.
DF E8+i  FUCOMIP ST, ST(i) Valid Valid     Compare ST(0) with ST(i), check for ordered values, set status flags accordingly, and pop register stack.

Description

Performs an unordered comparison of the contents of registers ST(0)
and ST(i) and sets the status flags ZF, PF, and CF in the EFLAGS
register according to the results (see the table below). The sign of
zero is ignored for comparisons, so that –0.0 is equal to +0.0.

Table 3-27. FCOMI/FCOMIP/ FUCOMI/FUCOMIP Results
Comparison Results* ZF PF CF
ST0 > ST(i)         0  0  0
ST0 < ST(i)         0  0  1
ST0 = ST(i)         1  0  0
Unordered**         1  1  1

// wbr

klalafuda ★☆☆
()

В шелле == для флоатов нет. Вернее оно есть, но тем кто его нашел можно доверять:)

> Да, я знаю, что в сиплюсплюсе через #define и перегрузку это реализуемо,

huh??

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

Re^2: А есть ли язык программирования, где нет == для float?

> ps: а вот использовать чёткое равенство ST0 = ST(i) или нет - это уже проблема конкретного девелупера.

Что-то я не придумал ни одного use case для этого сравнения. Они вообще бывают?

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

Re^4: А есть ли язык программирования, где нет == для float?

> Напр, функции могут передаваться вполне четкие константы, и ее логика может быть построена опираясь на это.

Высосано из пальца.

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

>что "тююю..." ? асм асму рознь =)

И че, я не смогу проверить на равентство вещественные числа с помощью целочисленной арифметики? :)

madcore ★★★★★
()

>> Напр, функции могут передаваться вполне четкие константы, и ее логика может быть построена опираясь на это.

>Высосано из пальца.


Почему? А если надо точно знать, что ноль - это именно ноль, а не 1E-45?

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

>> Высосано из пальца.

> Почему? А если надо точно знать, что ноль - это именно ноль, а не 1E-45?


Ну покажи мне реальную задачу в нашем непрерывном мире, где 0 означает одно, а +0 -- другое.

gaa ★★
() автор топика

А в чем проблема? Желании ЭПИК-геммороя?

anonymous
()
Ответ на: комментарий от gaa

>Ну покажи мне реальную задачу в нашем непрерывном мире, где 0 означает одно, а +0 -- другое.

Ну возьму любую функцию, у которой в нуле разрыв, а любые малые значения дают конечные результаты.

madcore ★★★★★
()

Возьми любой язык с перегрузкой операторов и пропиши там для «==» в случае float генерацию исключения. Или поменяй на сравнение abs(n1-n2) < eps :)

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

Re^2: А есть ли язык программирования, где нет == для float?

> Возьми любой язык с перегрузкой операторов и пропиши там для «==» в случае float генерацию исключения. Или поменяй на сравнение abs(n1-n2) < eps :)

Ну я же написал, что про это знаю. Интересует "искаропка".

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

Re^6: А есть ли язык программирования, где нет == для float?

> Например при опросе датчиков

Датчик отдаёт число+-погрешность датчика. "Чистого" нуля там возникнуть не может.

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

Re^6: А есть ли язык программирования, где нет == для float?

>>Ну покажи мне реальную задачу в нашем непрерывном мире, где 0 означает одно, а +0 -- другое.

> Ну возьму любую функцию, у которой в нуле разрыв, а любые малые значения дают конечные результаты.


Ну взял я sin(x)/x в окрестности нуля. И что? Где тот алгоритм, который, получая из интервала, который собой представляет x, какое-то число, делает вывод, который не был бы глуп и безоснователен?

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

Re^4: А есть ли язык программирования, где нет == для float?

>>Интересует "искаропка".
> Интересно, что с этим в Аде?


Да, и мне тоже.

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

> Интересно, что с этим в Аде?

во-первых не в Аде а в Аду, во-вторых, не думаю, что будучи в Аду подобные проблемы будут стоять на первом месте.

// wbr

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

> Ну покажи мне реальную задачу в нашем непрерывном мире, где 0 означает одно, а +0 -- другое.

метеорология

anonymous
()

> > ps: а вот использовать чёткое равенство ST0 = ST(i) или нет - это уже проблема конкретного девелупера.

> Что-то я не придумал ни одного use case для этого сравнения. Они вообще бывают?

Ну а как же проверка на NaN и Inf? http://en.wikipedia.org/wiki/Floating_point#Dealing_with_exceptional_cases

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

> Ну а как же проверка на NaN и Inf? http://en.wikipedia.org/wiki/Floating_point#Dealing_with_exceptional_cases

Мимо. Это может и записывается как ==NaN, но по сути идёт не побитное сравнение, как в обычном случае. Да и получение этих чисел обрабатывается особо.

Цитата с твоей же ссылки:

The two error values are "infinity" (often denoted "INF"), and "NaN" ("not a number"), which covers all other errors. "Infinity" does not necessarily mean that the result is actually infinite. It simply means "too large to represent".

Both of these are encoded with the exponent field set to all 1s. (Recall that exponent fields of all 0s or all 1s are reserved for special meanings.)

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

> Ну покажи мне реальную задачу в нашем непрерывном мире, где 0 означает одно, а +0 -- другое.

на практике встречал случай когда функция (из lapack) возвращала -0.0 и у дальнейшей логики съезжала крыша :)

MKuznetsov ★★★★★
()

Сравнение на равенство float это фигня!
Вот меня другая шняга беспокоит - деление на ноль! Почему результат деления не определен? ЭТО НЕУДОБНО! Куча проверок, исключеий и их обработок. Причем, каждый ламер-программер посвоему обрабатывает. От сюды полная анархия и разные результаты.
А вот если бы приняли что результат деления равен ГУГЛЫ (для тех кто не в курсе 10^100).
Как-то статейку читал, там дядька доказывал ято в природе, реально, нет такого числа, ибо, сосчитав все элементарные частички во вселенной получает только 10 в 40-й степени (не помню как число называется).
Не. Ну понятно, что аппаратные платформы (многие) не могут оперировать 10^100, но так это потому что кто-то когда-то придумал что на ноль делить нельзя!

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

Точно. -0.0 это задница при обращении матрицы, например

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

>> Ну покажи мне реальную задачу в нашем непрерывном мире, где 0 означает одно, а +0 -- другое.

> на практике встречал случай когда функция (из lapack) возвращала -0.0 и у дальнейшей логики съезжала крыша :)


Вывод: "дальнейшая логика" написана криво.

gaa ★★
() автор топика

Емнип, в brainfuck-e наверняка нету!

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

> но по сути идёт не побитное сравнение, как в обычном случае.

так в обычном случае тоже вовсе не побитовое сравнение флоатов.

$ cat test_float.c
int main()
{
  return (+0.f == -0.f);
}

$ gcc test_float.c

$ ./a.out

$ echo $?
1

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

> > у дальнейшей логики съезжала крыша :)

> Вывод: "дальнейшая логика" написана криво.

нужно руководствоваться принципом примата комбинаторной структуры..

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

>Как-то статейку читал, там дядька доказывал ято в природе, реально, нет такого числа, ибо, сосчитав все элементарные частички во вселенной получает только 10 в 40-й степени (не помню как число называется).

ФГМ

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

> А что, такое равенство недопустимо: x == Pi, где Pi == 2 arccos(0)?

Ну а ты сам попробуй. А потом попробуй (33.0*x)/3.0/11.0 == x.

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

>> но по сути идёт не побитное сравнение, как в обычном случае.
> так в обычном случае тоже вовсе не побитовое сравнение флоатов.

> (+0.f == -0.f);


Пересдавать зачёт по программированию, быстро!

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

> попробуй (33.0*x)/3.0/11.0 == x

Python 2.4.4 (#2, Apr 15 2008, 23:43:20)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 2.
>>> (33.0*x)/3.0/11.0 == x
True
>>>

И что? %)

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

>> попробуй (33.0*x)/3.0/11.0 == x

> И что? %)


Ну не попал, ладно. Для демонстрации эффекта обычно табулируют функцию (x+1)^2-x^2-2*x-1 с шагом эдак 0.000001 на каком-нибудь интервале.

При x=1e-5 результат оказался далеко не нулём, а очень даже ощутимым числом в 2.220446049250313e-16

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

>> Пересдавать зачёт по программированию, быстро!

> поподробней, плиз


Так ты пересдал или нет?

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

>>> попробуй (33.0*x)/3.0/11.0 == x

>> И что? %)

> Ну не попал, ладно.

Ничего личного, но ты уверен, что имеешь право посылать других на пересдачу? Чисто ради повторения материала, могбы и лобъяснить, что там не так с фразой dilmah про "побитовое сравнение" ;)

> Для демонстрации эффекта обычно табулируют функцию (x+1)^2-x^2-2*x-1 с шагом эдак 0.000001 на каком-нибудь интервале.

Те, кто этим занимаются, обычно понимают особенности работы плавающей арифметики.

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

> четко артикулируй претензии

Числа +0f и -0f будут восприняты как "чистый" 0 ещё компилятором. Соответственно, в момент сравнения окажутся побитово идентичными.

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

> Ничего личного, но ты уверен, что имеешь право посылать других на пересдачу? Чисто ради повторения материала, могбы и лобъяснить, что там не так с фразой dilmah про "побитовое сравнение" ;)

По твоей просьбе объяснил. Но вообще вопрос глуп.

> Те, кто этим занимаются, обычно понимают особенности работы плавающей арифметики.


А чаще на эти тонкости забивают. И это меня весьма удручает.

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

> Но вообще вопрос глуп.

Если я правильно понял, речь шла не о компиляторах, а о +0.0 и -0.0, получившихся в вычислениях.

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

>> Но вообще вопрос глуп.

> Если я правильно понял, речь шла не о компиляторах, а о +0.0 и -0.0, получившихся в вычислениях.


Неправильно понял. Там прямым текстом было написано:

> int main()

> {

> return (+0.f == -0.f);

> }:wq

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

ну во первых, компилятор не должен все-таки менять семантику.  Если
+0.f и -0.f различаются в рантайме, то он не должен при компиляции
считать их равными.

И потом, все равно сравнение флоатов это не побитовое сравнение:

$ cat test_float.c
float decimate(float x)
{
  for (; x != 0; x /= 10);
  return x;
}

int main()
{
  float x = decimate(1.f);
  float y = decimate(-1.f);

  return (x == y) + 16 * (*(int *)&x == *(int *)&y);
}

$ gcc test_float.c
$ ./a.out
$ echo $?
1

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

> И потом, все равно сравнение флоатов это не побитовое сравнение:

Почти побитовое. У этих нулей самый первый бит только различается, который знак определяет. А операции "вычитание" на него оказывается пофиг

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