Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
3 / 3 / 0
Регистрация: 28.11.2018
Сообщений: 238
1

Не понимаю как работает алгоритм

19.08.2019, 23:49. Показов 630. Ответов 11
Метки нет (Все метки)

Всем доброго времени суток. Настиг такой вопрос, с которым уже более недели не могу разобраться: искал везде, читал всё, на англоязычном инете ничего полезного не нашел(на русскоязычном вообще ничего толкового).

Просто в целом, вроде бы, ничего крайне сложного по коду(!!) нет, но вот числа..Вот здесь я и не понимаю абсолютно ничего! Почему мы берем именно такие большие числа, как придел того же uint? Ну тут ладно, можно еще понять, якобы для большего рандома(мин, макс больше).
Но вот почему A = 1'664'525 - вообще не понятно! - Почему? И почему когда я ставлю ..526 или ..524 то ничего не работает, на графике, в итоге, - просто прямая. Я думал, может быть это степень 2-ки - в итоге нет, может это кратно другим "непонятным" числам - тоже нет. Вот этот момент с числами вообще не ясен

PS: этот код был написан на Js, автор объяснил, опять же, ВСЁ, кроме чисел.
PPS: код можно запустить с консоли(нарисует символами), мб кому-то нужно..
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
typedef unsigned int uint;
#define CD static_cast<double>
#define CI static_cast<int>
double PerlinRand(uint M, uint A, uint C, uint &Z) {
    Z = (A * Z + C) % M;
    return CD(Z) / M;
}
void Draw(short x, short y, char c) {
    COORD p = { x, y };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), p);
    cout << c;
}
int main() {
    default_random_engine rnd(time(NULL));
    uint M = (1 << 32) - 1;//4294967295
    uint A = 1'664'525;
    uint C = 1;
    uint Z = static_cast<uint>
        ((CD(rnd() % 1'000'000'000) / 1'000'000'000) * M);
    int w = 1024;
    int h = 256;
    
    int x = 0;
    int y = h / 2;
    int amp = 3;
    int wl = 5;
    double a = PerlinRand(M, A, C, Z);
    double b = PerlinRand(M, A, C, Z);
    
    while (x < w) {
        if (x % wl == 0) {
            a = b;
            b = PerlinRand(M, A, C, Z);
            y = CI(h / 4 + a * amp);
 
            Draw(x, y, '0');
        }
        x += 1;
    }
    _getch();
    return 0;
}
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.08.2019, 23:49
Ответы с готовыми решениями:

Поделитесь информацией как работает компьютерная табуляция? Алгоритм действий её не понимаю
Мне нужно делать пробелы в тексте и одинаковой ширины.

программа работает алгоритм работы понимаю только как некоторые фрагменты кода работают не понятно!
вопросы написал в комментариях посмотрите пожалуйста! using System; using...

не понимаю, как составить алгоритм для данной задачи
для действительной матрицы порядка 4x5 найти сумму наибольших значений столбцов

Не понимаю как работает программа
Только изучаю программирование. В общем, try/catch, судя по всему, прога просто в первый catch идет...

11
1360 / 997 / 316
Регистрация: 28.07.2012
Сообщений: 2,759
20.08.2019, 00:34 2
Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
И почему когда я ставлю ..526 или ..524 то ничего не работает
Не знаю, у меня работает.

Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
Не понимаю как работает алгоритм
А что он делает?

Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
(1 << 32) - 1
Тут неопределенное поведение. Замени лучше на ~0u.
0
3 / 3 / 0
Регистрация: 28.11.2018
Сообщений: 238
20.08.2019, 01:25  [ТС] 3
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Не знаю, у меня работает.
Ну должна быть волна с определенной частотой. А частоты нет - 0 - прямая линия - не работает.
Цитата Сообщение от nonedark2008 Посмотреть сообщение
А что он делает?
Прошу прощения, забыл указать главное, это PERLIN NOISE 1D, шум Перлина. Просто генератор шумов
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Тут неопределенное поведение
Почему UB??
0
1360 / 997 / 316
Регистрация: 28.07.2012
Сообщений: 2,759
20.08.2019, 08:39 4
Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
Почему UB?
В uint 32 бита. Сдвиг за эти пределы - это UB.
8.8 Shift operators [expr.shift]
The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
Добавлено через 14 минут
Боюсь, что автор твоего кода просто подогнал числа так, чтобы хоть что-то как-то отображалось. По моему мнению, это глупость выводить график в консоли символами.

Если код сдернут отсюда, то там есть комментарии к переменным. В частности по твоему вопросу:
A - 1 should be divisible by m's prime factors
Добавлено через 12 минут
Теперь понятно. Твоя функция PerlinRand - это обычный линейный конгруэнтный генератор (генератор псевдослучайных чисел). К шуму Перлина не имеет прямого отношения.
1
3 / 3 / 0
Регистрация: 28.11.2018
Сообщений: 238
20.08.2019, 10:59  [ТС] 5
Цитата Сообщение от nonedark2008 Посмотреть сообщение
По моему мнению, это глупость выводить график в консоли символами.
Это реализовано в основном проекте, с консолью там не работаю А здесь просто для наглядности
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Твоя функция PerlinRand - это обычный линейный конгруэнтный генератор
А вот это очень интересно, спасибо! А как вы узнали, если не секрет, какой это..генератор??

Добавлено через 5 минут
nonedark2008, кстати, если это поделить(что уже пробовал) ~0u / 1664525 то получается дробное число. А как я понял из перевода, оно должно делиться полностью и нацело(иначе +-1 к этому числу - и работало бы также)
0
1360 / 997 / 316
Регистрация: 28.07.2012
Сообщений: 2,759
20.08.2019, 14:00 6
Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
А как вы узнали, если не секрет, какой это..генератор?
В приведенной мной ссылке это было написано. Да и по самой формуле понятно. Если хочется подробнее узнать про генераторы, то советую почитать Кнута.

Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
если это поделить(что уже пробовал) ~0u / 1664525 то получается дробное число
Нет, число A-1 должно нацело делиться на все простые делители числа M.

Присмотревшись поближе к твоему кода, увидел ошибки:
1) Вышеуказанное мной требование не соблюдается;
2) В генераторе при расчете значений происходит переполнение.

Сделай, например, вот так:
C++
1
2
3
4
5
6
7
double PerlinRand(uint &Z) {
    uint64_t M = uint64_t(1) << 32;
    uint64_t A = 1'664'525;
    uint64_t C = 1;
    Z = static_cast<uint>((A * Z + C) % M);
    return static_cast<double>(Z) / M;
}
1
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.08.2019, 14:33 7
Цитата Сообщение от nonedark2008 Посмотреть сообщение
В uint 32 бита. Сдвиг за эти пределы - это UB.
UB там когда мы пытаемся шифтить литерал типа signed int.
1 << 32
правильно писать :
1ULL << 32
А с без знаковыми UB нету, ибо они не оверфловятся.
The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2^E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1×2^E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: “unsigned char”, “unsigned short int”, “unsigned int”, “unsigned long int”, and “unsigned long long int”. Likewise, for each of the extended signed integer types, there exists a corresponding extended unsigned integer type. The standard and extended unsigned integer types are collectively called unsigned integer types. An unsigned integer type has the same width N as the corresponding signed integer type. The range of representable values for the unsigned type is 0 to 2N−1(inclusive); arithmetic for the unsigned type is performed modulo 2N. [ Note: Unsigned arithmetic does not overflow. Overflow for signed arithmetic yields undefined behavior ([expr.pre]). — end note ]
Но вариант с ~0u конечно намного лучше.
1
1360 / 997 / 316
Регистрация: 28.07.2012
Сообщений: 2,759
20.08.2019, 15:27 8
Цитата Сообщение от Azazel-San Посмотреть сообщение
А с без знаковыми UB нету
Там же в предыдущем пункте стандарта написано, что если сдвиг производится на количество бит, превышающее либо равное размеру типа, то это UB.
1
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.08.2019, 18:52 9
Цитата Сообщение от nonedark2008 Посмотреть сообщение
что если сдвиг производится на количество бит, превышающее либо равное размеру типа, то это UB.
Похоже у вас немного старее стандарт. Вот что сейчас пишут:
Цитата Сообщение от http://eel.is/c++draft/expr.shift
The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the width of the promoted left operand.
http://eel.is/c++draft/expr.shift
Ну, в моем случае все верно, 1ULL << 32 здесь литерал 1 типа unsigned long long, то где здесь UB?
For unsigned a, the value of a << b is the value of a * 2b, reduced modulo 2N where N is the number of bits in the return type (that is, bitwise left shift is performed and the bits that get shifted out of the destination type are discarded).
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
20.08.2019, 19:10 10
Цитата Сообщение от Azazel-San Посмотреть сообщение
Похоже у вас немного старее стандарт. Вот что сейчас пишут:
То же, что и раньше.
Цитата Сообщение от http://eel.is/c++draft/expr.shift#1.sentence-4
The behavior is undefined if the right operand is negative, or greater than or equal to the width of the promoted left operand.
0
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.08.2019, 19:56 11
rat0r, это с какой стороны смотреть)
Суть не изменилась, но если придираться к словам, то изменилось: to the length in bits было заменено на to the width )
Цитата Сообщение от nonedark2008 Посмотреть сообщение
8.8 Shift operators [expr.shift]
The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
0
nonedark2008
20.08.2019, 23:24     Не понимаю как работает алгоритм
  #12

Не по теме:

Цитата Сообщение от Azazel-San Посмотреть сообщение
Похоже у вас немного старее стандарт
По разным компьютерам разбросаны разные черновики. Какой найдется, такой и смотрю. ;)

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.08.2019, 23:24

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Не понимаю как работает функция
Прохожу видео уроки и тут появился вопрос как работает функция $function() которую до этого момента...

Не понимаю как работает scanf
Здравствуйте, вот код программы. При работе программы второй scanf пропускается. Почему так...

Не понимаю как работает рекурсия
Привет. Знаю, что таких тем много (Я читал их). Не нужно кидать ссылки. Я знаю что такое рекурсия,...

Не понимаю как работает цикл!
Приветствую! Начал долбить пхп... Есть код: function mult ($a) { static $result=1; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.