Исполнять код после ввода каждого символа — плохая идея.
Если пользователь начинает набирать for (var i = 0; i < 10; i++), то обычно сначала набирают for(), потом var i = 0; i < 10; — и вот тут всё повиснет.
Автор, вот тест который показывает странное поведение этого алгоритма: codepad.org/a6bQS54E
Легко заметить, что все точки треугольника лежат в районе точки (-1, -1, 0), а тестируемая точка в (1, 1, 0)
Объясни пожалуйста, почему функция проверки иногда возвращает 1?
Да сколько уже можно публиковать безграмотный код?
4 байта.
Проявление этой ошибки зависит от инструкций и их порядка. И будет скорее всего разное при разных настройках компилятора.
Можешь попробовать повычислять с числами такого же порядка, в цикле.
И ещё вдогонку, в приведённой функции после того как поставить скобки после условия в while, всё разно есть ещё одна ошибка,
Она связана с неучтённой погрешностью float.
Как и предполагалось, rand не виноват.
Полосы на картинке с ним — это артефакт работы заполнителя массива с числами, максимальное из которых сравнимо с 1000
for (int i = 0; i < 2000000; i++)
{
int val = rand();
for (int ix = 1; ix <= sz; ix++)
if (max_rand - val > ix) //это должно было быть отсечение "плохих" чисел рядом с 32768, но оно не работает
hists[ix - 1][val % ix] ++;
}
С этим алгоритмом можно у любого генератора случайных чисел оставить последние 15 бит (random() & 0x7fff) и получить аналогичную картину.
Кстати, полосы проявятся лучше, если оставить ещё меньше бит в случайном числе.
Вот картина, для которой максимальное случайное число было 0xfff:
А начнем мы со стандартного С-шного генератора rand
Если автор использовал версию rand() которая не может возвращать числа больше чем 32767, получал остаток от деления на числа порядка 100 — 1000 которые не являются степенью двойки, то он ошибся.
Например, выражение rand() % 1000 будет выдавать числа от 0 до 767 заметно чаще, чем от 768 до 999.
Тут проблема не в rand, а в его использовании.
Предлагаю первый график для rand перестроить. Взять в качестве функции (rand() << 15) ^ rand() или int a = rand(); return (a << 15) ^ a;
@echo off
set /a x=123456789+%random%
set /a y=362436069+%random%
set /a z=521288629+%random%
:1
set /a "x ^= x << 16"
set /a "x ^= x >> 5"
set /a "x ^= x << 1"
set /a "t = x"
set /a "x = y"
set /a "y = z"
set /a "z = t ^ x ^ y"
set /a "a = z & 1"
if %a%==0 set /p "t=/"<nul & goto 1
if %a%==1 set /p "t=\"<nul & goto 1
Если пользователь начинает набирать for (var i = 0; i < 10; i++), то обычно сначала набирают for(), потом var i = 0; i < 10; — и вот тут всё повиснет.
Легко заметить, что все точки треугольника лежат в районе точки (-1, -1, 0), а тестируемая точка в (1, 1, 0)
Объясни пожалуйста, почему функция проверки иногда возвращает 1?
Да сколько уже можно публиковать безграмотный код?
Проявление этой ошибки зависит от инструкций и их порядка. И будет скорее всего разное при разных настройках компилятора.
Можешь попробовать повычислять с числами такого же порядка, в цикле.
Она связана с неучтённой погрешностью float.
Вход 1e18: codepad.org/qK4Bs558 — выполняется
Вход 1e20: codepad.org/7Rwyo0gh — бесконечный цикл
Вход 1e22: codepad.org/Ry9iRGbZ — выполняется
Автор, ты сам запускал этот код перед тем как постить?
Полосы на картинке с ним — это артефакт работы заполнителя массива с числами, максимальное из которых сравнимо с 1000
С этим алгоритмом можно у любого генератора случайных чисел оставить последние 15 бит (random() & 0x7fff) и получить аналогичную картину.
Кстати, полосы проявятся лучше, если оставить ещё меньше бит в случайном числе.
Вот картина, для которой максимальное случайное число было 0xfff:
Действительно, очень важная константа для описания множества целых чисел.
Если автор использовал версию rand() которая не может возвращать числа больше чем 32767, получал остаток от деления на числа порядка 100 — 1000 которые не являются степенью двойки, то он ошибся.
Например, выражение rand() % 1000 будет выдавать числа от 0 до 767 заметно чаще, чем от 768 до 999.
Тут проблема не в rand, а в его использовании.
Предлагаю первый график для rand перестроить. Взять в качестве функции (rand() << 15) ^ rand() или int a = rand(); return (a << 15) ^ a;
хороший генератор с периодом 2^96-1