Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 4
1

Для чего в rand() использовано приведение типа к (unsigned int)?

28.06.2019, 01:30. Показов 1122. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В учебнике Кернигана Ритчи "Язык программирования С" приведена функция rand() из стандартной библиотеки, которая генерирует псевдослучайные числа. Написано что она иллюстрирует приведение типов и что она переносима между системами. Вот её код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
unsigned long int next=1;
 
/*rand возвращает псевдослучайное число от 0 до 32767 */
int rand(void)
{
next=next*1103515245 + 12345;
return (unsigned int)(next / 65536) % 32768;
}
/*srand устанавливает инициализатор для rand*/
void srand(unsigned int seed)
{
next=seed;
}
Вопрос в том, что я никак не могу понять для чего здесь вообще приведение к типу (unsigned int)? Книга 90ых годов, когда ещё int был 16 битным на многих системах. Так вот мои суждения такие, что обе константы в данной строке будут signed long int (в книге написано что десятичные константы не могут быть unsigned int, а только unsigned long int). Переменная next это unsigned long int и результат его деления на 65536 будет тоже unsigned long int. Далее он приводится к unsigned int возможно при этом урезаясь до 16 бит, но потом тут же опять будет преобразован в long int, потому как 32768 это long int. Зачем это всё надо? Подозреваю, что для переносимости, но я думал пол дня над этим и так и не понял для чего может пригодиться это приведение типа. Если кто знает для чего оно, объясните пожалуйста.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.06.2019, 01:30
Ответы с готовыми решениями:

Определение типов. Приведение int к unsigned int
При таком определении 5 рассматривается как int. Как при определении указать что 5 будет именно...

Const unsigned int flags - для чего эти флаги?
Кто может подсказать что это за флаги Const unsigned int flags , для чего они нужны и какие бывают)...

Поместить двоичный код, в веденной строке, в переменную типа int и unsigned int.
Пользователь вводит двоичную строку (32 символа). Поместить двоичный код, в веденной строке, в...

Создать класс для работы с одномерными динамическими массивами значений типа unsigned int
Помогите пожалуйста с задачей. Создать класс для работы с одномерными динамическими массивами...

7
163 / 70 / 39
Регистрация: 28.05.2019
Сообщений: 241
28.06.2019, 03:42 2
Цитата Сообщение от magbit Посмотреть сообщение
Книга 90ых годов
Зачем такие книги вообще читать? Вернее понятно зачем, можно почитать какие-то общие рекомендации, но вдумываться в код я бы не стал
0
Mental handicap
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
28.06.2019, 09:18 3
magbit, если речь об С99 то, мне кажется что здесь дело в том что бы оператор % возвращал значение с правильным знаком, т.к. в Си знак результата был таким же как и знак делителя, в то время как результатом остачи от деления ожидался знак делителя. Т.к в Си оператор % - это не совсем тот modulus оператор.
Т.е. если результат next / 65536 == -1 при касте к unsigned мы получали тот же -1 только в плюсом диапазоне что равно 4294967295, т.е. это тоже бинарное представление числа -1 == 0xFFFFFFFF.
1
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 4
28.06.2019, 13:41  [ТС] 4
Да возможно это связано с делением по модулю, в книге как раз упоминается, что в разных системах оно было реализовано по разному, но только вот можно ли получить отрицательное число деля unsigned long int next на 65536, которое signed long int и при расширении до unsigned в старших битах будут всё так же нули. Результатом этого деления так же будет число у которого старшие 16 бит нули. При приведении его к 16 битам без знака эти нули просто обрезаются.
Единственное объяснение которое приходит в голову, это что 32768 записано как 16 битный инт со знаком и если его расширять до лонга, то оно расширится со знаком, то есть все старшие биты будут единицами. Но это звучит просто абсурдно.
Эта функция rand приведена в книге в разделе про приведение типов и она там по сути именно из-за этого (unsigned int), а я хоть убей не понимаю зачем он там, соответственно видимо я что-то не понимаю в самом приведении типов.
0
Mental handicap
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
28.06.2019, 14:37 5
Цитата Сообщение от Azazel-San
т.к. в Си знак результата был таким же как и знак
делителя
Поправка не делителя, а делимого.
magbit, при касте к беззнаковому, знака быть не может. Потом почему вы решили что long int > unsigned int?
Что вы так обострили внимание на этих 16 битах?
0
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 4
28.06.2019, 17:14  [ТС] 6
Вот в том то и дело что я не понимаю. При касте к беззнаковому знака быть не может, но и при делении беззнакового делимого next тоже ведь знака быть не должно. Зачем тогда Ритчи заостряет внимание на приведении (unsigned int) если без него результат был бы абсолютно одинаковым во всех системах?

Добавлено через 20 минут
Или давайте просто предположим, что приведения нет. У нас самый большой тип здесь unsigned long int у next. При каждой операции все операнды будут преобразованы к нему и только в конце при возврате он преобразуется в обычный int. Из производимых вычислений следует что у результата старшие 17 бит будут нулями, то есть при приведении не получится, что слишком большое число без знака превращается в отрицательное. Где тут что-то может пойти не так?
0
Mental handicap
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
28.06.2019, 18:28 7
Цитата Сообщение от magbit Посмотреть сообщение
но и при делении беззнакового делимого next тоже ведь знака быть не должно
По стандарту, да. Тк у беззнакового приоритет больше согласно правилам каста, но может когда писали книгу таких правил еще не было? Или просто лишняя предосторожность?
0
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 4
28.06.2019, 19:54  [ТС] 8
Эх, видимо Ритчи решил затралить таким образом своих потомков У него самого уже не узнаешь, что он имел ввиду.Может быть лет через 10 до меня всё-таки дойдёт для чего там был этот треклятый (unsigned int). Буду надеяться на лучшее.
0
28.06.2019, 19:54
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.06.2019, 19:54
Помогаю со студенческими работами здесь

Для чего нужны переменные типа CHAR, SIGNED INT?
Привет всем. Я новичок в С++, в принципе я знаю, как программировать, изучил паскаль до функций с...

Перевод массива unsigned char в число типа int
Добрый день всем! Есть массив, который заполняется трехзначным числом, введенным с клавиатуры...

Приведение типа Double в int
у меня есть тип double, мне нужно конвертировать его в инт и перенести в текст бокс double a =...

Не умещается значение = 4млрд, в переменной типа unsigned long int
Всем привет. В Си я новичек. Пользуюсь VS6. Написал вот это: #include <stdio.h> main() {...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru