LuaJIT меня убил
Автор: AntonioModer
LuaJIT подводные камни:
Автор: AntonioModer
LuaJIT подводные камни:
#include <stdio.h> #include <time.h> #include <math.h> int main() { int i, j; long t1, t2, t3; double r; t1 = clock(); for (i = 0; i < 10; ++i) { for (j = 0; j < 10000000; ++j) { r = cos(1); } } t1 = clock() - t1; printf("test1 = %f\n", (float)t1 / CLOCKS_PER_SEC); t2 = clock(); for (i = 0; i < 10000000; ++i) { for (j = 0; j < 10; ++j) { r = cos(1); } } t2 = clock() - t2; printf("test2 = %f\n", (float)t2 / CLOCKS_PER_SEC); return 0; }
Аналогично
arprog
> Аналогично
Серьезно? о.О
Вот так раз.
Я не программировал на С++, поэтому не знал.
В книге Программирование на Lua - Роберту Иерузалимски, это как раз очень подробно объясняется, почему всё происходит именно так, а не иначе. Или можешь просто запомнить как факт, что инициализация каждого нового цикла, критичнее итерации, в любом языке программирования.
> Или можешь просто запомнить как факт, что инициализация каждого нового цикла, критичнее итерации, в любом языке программирования.
Crunatus
slava_mib
for состоит из фазы инициализации, последовательного вызова итерирующей функции, и собственно тела.
В первом случае, мы 10 раз инициализируем новый цикл, во втором 10000000.
Сама итерирующая функция выполняет минимум действий в отличии от инициализации, поэтому первый вариант, всегда будет выполняться быстрее второго.
Еще одну шнягу нашел:
2.001 - 2 == 0.00099999999999989
нужно 2.001 - 2 == 0.001
Жесть.
Правильно будет так:
string.format('%0.3f', 2.001 - 2) == 0.001
Это ж скоко гемора будет, ааа!
У меня бомбит очень-очень. :D :(
> for состоит из фазы инициализации, последовательного вызова итерирующей функции, и собственно тела.
Crunatus, теперь понял.
> Жесть.
AntonioModer, такие ошибки - это вцелом норма, не только для ЛУА, а вообще.
slava_mib
> такие ошибки - это вцелом норма, не только для ЛУА, а вообще.
И как с ними бороться правильно?
AntonioModer
> И как с ними бороться правильно?
Просто не сравнивают дробные числа на равенство. Вместо этого проверяют, что абсолютная разность меньше эпсилон. Но тут тоже не всегда понятно, какое эпсилон брать.
gammaker
> Просто не сравнивают дробные числа на равенство.
Мне нужна была разность, т.е. дробная часть.
Тоже самое получается не верно: 2.001%1 = 0.00099999999999989
AntonioModer
потому что флоаты храняться в двоичной системе, а не в десятичной. 0.5 или (1/1024) в них представить можно, а 0.001 - нельзя, в двоичной системе это бесконечная дробь. А если ее округлить получается число которое ты написал.
Короче, просто смирись с тем что нет никаких "==", числа всегда могут отличаться где-то в младшем разряде.
kipar
> Короче, просто смирись с тем что нет никаких "==", числа всегда могут
> отличаться где-то в младшем разряде.
Я уже смирился :(
Самое паскудное, что придется числа контролировать постоянно.
Пересмотрел в книге Lua про числа, Роберту пишет об этом случае.
>> string.format('%.16f', 2.001) 2.0009999999999999 >> string.format('%.16e', 0x2.004189374bc6a0-2) 9.9999999999988987e-004 >> string.format('%.16e', 0x2.004189374bc6af-2) 9.9999999999988987e-004 >> string.format('%.16e', 0x2.004189374bc6b-2) 1.0000000000003340e-003
АнтониоМодер, знакомься, это плавающий питух. Плавающий питух, знакомься, это АнтониоМодер.
А в качестве домашнего задания ты должен рассказать, почему если math.sin(math.pi) возвращает ноль - это ошибка.
Delfigamer
> АнтониоМодер, знакомься, это плавающий питух.
А почему его питухом называют? Откуда вообще это слово взялось?
Тема в архиве.