Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Chorkov, Вы писали:
C>>Здравствуйте, C>>Подозреваю, что нашел ошибку компилятора. А>Сравнивать даблы по значению нельзя.
Здравствуйте, Chorkov, Вы писали:
C>Подозреваю, что нашел ошибку компилятора.
Сделай минимальный пример воспроизводящий ошибку, убери лишний шум — желающих помочь будет больше.
На каких уровнях оптимизации /O? проявляется?
C>Проявляется в релизе на 2012-я студии (17.00.61030).
В VS2012 где-то был баг, связанный с floating point — здесь как-то проскакивала подобная тема.
Проявляется при оптимизации -O2. (-O1 — ошибки нет, но у меня производительность критична.)
При убирании '-' в цикле в foo — ошибка пропадает.
При удалении добавлении любого дополнительного кода внутрь цикла в foo, тое пропадает.
Поэтому и грешу на оптимизатор.
Про сравнение чисел с плавающей точкой я знаю. Оператор == появился при сублимировании кода.
Здравствуйте, Аноним, Вы писали:
C>>>>Подозреваю, что нашел ошибку компилятора. А>>>Сравнивать даблы по значению нельзя. G>>В данном случае можно. А>Нельзя никогда, если два дабла получены в результате вычислений.
Это всего лишь rule of dumb, подходящий для 99% случаев.
В общем случае их можно сравнивать. Особенно когда работа с такими числами регламентирована стандартами, например IEEE 754 (fpu большинства современного железа реализуют этот стандарт).
Например, как минимум одинаковые вычисления (в точности до последовательности всех операций), должны давать одинаковый бинарный результат (при одинаковых флагах fpu).
А>Умножение на минус единицу ничем в этом плане не отличается.
Единица в IEEE 754 binary64 представляется точно, знак это всего лишь отдельный бит — поэтому никаких проблем с проверкой быть не должно. (это в общем, в код ТС я пока не вникал)
Здравствуйте, Chorkov, Вы писали:
C>Проявляется при оптимизации -O2. (-O1 — ошибки нет, но у меня производительность критична.) C>При убирании '-' в цикле в foo — ошибка пропадает. C>При удалении добавлении любого дополнительного кода внутрь цикла в foo, тое пропадает. C>Поэтому и грешу на оптимизатор.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Аноним, Вы писали:
C>>>>>Подозреваю, что нашел ошибку компилятора. А>>>>Сравнивать даблы по значению нельзя. G>>>В данном случае можно. А>>Нельзя никогда, если два дабла получены в результате вычислений.
EP>Это всего лишь rule of dumb, подходящий для 99% случаев.
Это то, о чем нужно думать, прежде, чем кричать о найденой ошибке в компиляторе.
EP>В общем случае их можно сравнивать. Особенно когда работа с такими числами регламентирована стандартами, например IEEE 754 (fpu большинства современного железа реализуют этот стандарт). EP>Например, как минимум одинаковые вычисления (в точности до последовательности всех операций), должны давать одинаковый бинарный результат (при одинаковых флагах fpu).
А кто вообще гарантирует, что вычисления будут одинаковыми с точностью до инструкций? Что оптимизатор одинаково их заоптимизирует в друх разных местах, например?
EP>Единица в IEEE 754 binary64 представляется точно, знак это всего лишь отдельный бит — поэтому никаких проблем с проверкой быть не должно. (это в общем, в код ТС я пока не вникал)
никто никому ничего не должен. Что именно решит компилятор — его дело. Он может реализовать умножение так, как ему удобнее, а не так, как вы думаете.
Здравствуйте, Аноним, Вы писали:
C>>>>>>Подозреваю, что нашел ошибку компилятора. А>>>>>Сравнивать даблы по значению нельзя. G>>>>В данном случае можно. А>>>Нельзя никогда, если два дабла получены в результате вычислений. EP>>Это всего лишь rule of dumb, подходящий для 99% случаев. А>Это то, о чем нужно думать, прежде, чем кричать о найденой ошибке в компиляторе.
Так а кто кричит? Коллега даже знак вопроса в сабже поставил
EP>>В общем случае их можно сравнивать. Особенно когда работа с такими числами регламентирована стандартами, например IEEE 754 (fpu большинства современного железа реализуют этот стандарт). EP>>Например, как минимум одинаковые вычисления (в точности до последовательности всех операций), должны давать одинаковый бинарный результат (при одинаковых флагах fpu). А>А кто вообще гарантирует, что вычисления будут одинаковыми с точностью до инструкций? Что оптимизатор одинаково их заоптимизирует в друх разных местах, например?
С точностью до инструкции нет гарантий, а вот до получения тех же значений — вполне. Именно для этого и существуют такие настройки компиляторов как floating-point behavior, с /fp:precise по умолчанию. Например, fp сложение не ассоциативно — оптимизатор не может просто взять и "переставить скобки" в (a+b)+c — так как это влияет на результат.
Или, например, настройка fp rounding.
Другой пример — см. какие свойства есть в std::numeric_limits, то есть в ISO C++.
EP>>Единица в IEEE 754 binary64 представляется точно, знак это всего лишь отдельный бит — поэтому никаких проблем с проверкой быть не должно. (это в общем, в код ТС я пока не вникал) А>никто никому ничего не должен. Что именно решит компилятор — его дело. Он может реализовать умножение так, как ему удобнее, а не так, как вы думаете.
Компилятор конечно может сделать что угодно, хоть чайник вскипятить.
Но я говорю про те компиляторы, которые лично проверял — GCC, MSVC и частично Clang, причём разных версий, на разных архитектурах. Регулярно гоняю достаточно длинные цепочки fp вычислений на unit-test'ах — результаты идентичны вплоть до бинарного представления.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Да, видимо так и есть. Немного сократил:
Ты можешь завести баг на сайте мс и отправить им этот пример, интересно что ответят.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
EP>>Да, видимо так и есть. Немного сократил: V>Ты можешь завести баг на сайте мс и отправить им этот пример, интересно что ответят.
Я-то могу (недавно заводил по поводу ICE), но тут есть два момента:
1. Мне кажется здесь уже проскакивал подобный баг (именно в VS2012), хорошо бы найти ту тему и сравнить.
2. Это VS2012(причём не обновлённый), а уже есть VS2013, которого у меня нет под рукой. Нужно в первую очередь проверить на VS2013.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>2. Это VS2012(причём не обновлённый), а уже есть VS2013, которого у меня нет под рукой. Нужно в первую очередь проверить на VS2013.
Здравствуйте, ArtDenis, Вы писали:
AD>Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>2. Это VS2012(причём не обновлённый), а уже есть VS2013, которого у меня нет под рукой. Нужно в первую очередь проверить на VS2013.
AD>На VS2013 не проявляется.
Проявляется
+> cl vs.cpp /O2
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
vs.cpp
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\xlocale(337) : warning C4530: C++ exception handler used, but unwind semantics are not
enabled. Specify /EHsc
Microsoft (R) Incremental Linker Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
Здравствуйте, Кодт, Вы писали:
К>Пожалуйста, укажи командную строку полностью.
x64:
D:\WB\tests\test_msvc_o2>cl -O2 main.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocale(336) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
Microsoft (R) Incremental Linker Version 11.00.61030.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
main.obj
D:\WB\tests\test_msvc_o2>main.exe
Error!!! : i=1 omega=-12 -J=-22
Error!!! : i=3 omega=-34 -J=-44
x86 — тоже самое
D:\WB\tests\test_msvc_o2>cl -O2 main.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocale(336) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
Microsoft (R) Incremental Linker Version 11.00.61030.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
main.obj
D:\WB\tests\test_msvc_o2>main.exe
Error!!! : i=1 omega=-12 -J=-22
Error!!! : i=3 omega=-34 -J=-44
Error!!! : i=5 omega=-56 -J=-66