鱼C论坛

 找回密码
 立即注册
查看: 2029|回复: 14

[已解决]隨機數種子的範圍

[复制链接]
发表于 2022-5-16 21:51:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 一隻太平洋睡鯊 于 2022-5-16 21:53 编辑

在前一個問題帖
收到了這個答覆
https://www.zhihu.com/question/3 ... D%E8%A8%80%E6%88%96,ND_SEED%E3%80%82
在這裡面有寫到
"1) 首先给srand()提供一个种子,它是一个unsigned int类型,其取值范围从0~65535;"
我的教材也寫種子是一個無號整數
可是教材內對於無號型態的介紹是這樣
是不是教材有寫錯...?
到底無號整數(unsigned int)的範圍是多少?
0-65535的名稱到底叫啥?
隨機數種子的範圍是多少?
無號整數(unsigned int)和無號長整數(unsigned long int)的範圍確實一樣?
最佳答案
2022-5-17 10:40:05
一隻太平洋睡鯊 发表于 2022-5-17 10:24
這麼說來,隨機種子的內容,不是由C語言本身決定,而是由編譯器來決定的?
即使視同一個數值的隨機種 ...

這麼說來,隨機種子的內容,不是由C語言本身決定,而是由編譯器來決定的?
C語言标准没有规定int的大小,int的大小是由编译器的作者决定的

即使視同一個數值的隨機種子(比如srand(1))
也有可能因為編譯器的不同,而呈現不一樣的算法嗎?
这我就不知道了,我没有研究过这部分的内容
就算是随机算法一样,隨機種子的范围不一样,我想给出的结果应该也是不一样的
$ cat main.c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    srand(1);
    for(size_t i = 0; i < 10; ++i) {
        printf("%d\n", rand());
    }
    return 0;
}
$ gcc -g -Wall -o main main.c
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ clang -g -Wall -o main main.c
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$

1.png
2.png
281401333_525422715746931_3977268785783129554_n.jpg
280301419_1811339602409556_5166861492876378140_n.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-5-16 22:03:20 | 显示全部楼层
是的,教材中写的是错误的
标准只规定了char是一个字节,其他的都没有规定
int并不是4个字节
long可以和int一样,也可以和int不一样
$ cat main.c
#include <stdio.h>

int main(void) {
    printf("%d\n", (int)sizeof(int));
    printf("%d\n", (int)sizeof(long));
    return 0;
}
$ gcc -g -Wall -o main main.c
$ ./main
4
8
$ gcc -m32 -g -Wall -o main main.c
$ ./main
4
4
$

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
一隻太平洋睡鯊 + 1 + 1 + 1 感謝回覆

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-16 22:08:58 | 显示全部楼层
tc给出的结果是
int 是 2
long 是 4
标准只规定了char是一个字节,其他的都没有规定

1.png
2.png

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
一隻太平洋睡鯊 + 1 + 1 + 1 感謝回覆

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-16 22:42:33 | 显示全部楼层
人造人 发表于 2022-5-16 22:08
tc给出的结果是
int 是 2
long 是 4

字節=位元嗎?
2(字節/位元)是0~65535?
4(字節/位元)是0-4294967295?
所以
無號整數(unsigned int)的範圍是0~65535?
0-65535的名稱可以是無號整數(unsigned int)或無號短整數(unsigned short int)?
還是沒有無號短整數(unsigned short int)這個詞?
隨機數種子的範圍是0~65535?
無號整數(unsigned int)和無號長整數(unsigned long int)的範圍不一樣?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-16 23:08:36 | 显示全部楼层
一隻太平洋睡鯊 发表于 2022-5-16 22:42
字節=位元嗎?
2(字節/位元)是0~65535?
4(字節/位元)是0-4294967295?

字節=位元,应该是这样的,我们这边叫字节,你们那边应该就是位元
1个字节是8位,2^8(2的8次方)是256,取值范围就是0~255
2个字节就是16位,就是2^16,就是65536,取值范围就是0~65535
4个字节就是2^32,就是4294967296,取值范围就是0~4294967295
unsigned int不是0~65535,这要看int是多少字节,如果int是2个字节,unsinged int就是0~65535
如果int是4个字节,unsinged int就是0~4294967295,如果int是一个字节,unsinged int就是0~255
问题是不知道int是多少个字节,也就不知道int的取值范围,当然也就不知道unsigned int的范围
隨機數種子的范围不是0~65535,隨機數種子的范围就是unsigned int的范围
不知道unsinged int的范围是多少,也就不知道隨機數種子的范围
unsigned int 和 unsigned long int 的范围可以一样,也可以不一样,标准没有规定这个,这个具体是有编译器的作者来决定的,编译器的作者可以选择让这两个一样,也可以让这两个不一样
标准只规定了char是一个字节,其他的都没有规定
使用sizeof运算符可以得到其他类型的大小

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
一隻太平洋睡鯊 + 5 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-16 23:12:04 | 显示全部楼层
不同的编译器,甚至是同一个编译器,不同的编译选项,只有char是一样的,是1
其他类型可以一样,也可以不一样
$ cat main.c
#include <stdio.h>

int main(void) {
    printf("%d\n", (int)sizeof(char));
    printf("%d\n", (int)sizeof(short));
    printf("%d\n", (int)sizeof(int));
    printf("%d\n", (int)sizeof(long));
    printf("%d\n", (int)sizeof(long long));
    printf("%d\n", (int)sizeof(float));
    printf("%d\n", (int)sizeof(double));
    return 0;
}
$ gcc -g -Wall -o main main.c
$ ./main
1
2
4
8
8
4
8
$ gcc -m32 -g -Wall -o main main.c
$ ./main
1
2
4
4
8
4
8
$

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
一隻太平洋睡鯊 + 1 + 1 + 1 感謝回覆

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-16 23:15:50 | 显示全部楼层
1.png
2.png

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
一隻太平洋睡鯊 + 1 + 1 + 1 感謝回覆

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-17 09:50:00 | 显示全部楼层
人造人 发表于 2022-5-16 23:08
字節=位元,应该是这样的,我们这边叫字节,你们那边应该就是位元
1个字节是8位,2^8(2的8次方)是256, ...

所以隨機種子是沒有範圍的?
任何4294967295以內的正整數都能夠放進srand()裡面?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-17 09:54:49 | 显示全部楼层
一隻太平洋睡鯊 发表于 2022-5-17 09:50
所以隨機種子是沒有範圍的?
任何4294967295以內的正整數都能夠放進srand()裡面?

有范围,范围就是unsigned int的范围
sizeof(unsigned int) 得到 unsigned int的大小
知道了unsigned int的大小就知道了unsigned int的范围,就知道了隨機種子的范围

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
一隻太平洋睡鯊 + 1 + 1 + 1 感謝回覆

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-17 10:01:13 | 显示全部楼层
人造人 发表于 2022-5-17 09:54
有范围,范围就是unsigned int的范围
sizeof(unsigned int) 得到 unsigned int的大小
知道了unsigned i ...

我用了這個代碼,輸出是4,就是0~4294967295?
所以我開頭放的那個網站裡面寫的是錯的?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-17 10:13:55 | 显示全部楼层
$ cat main.c
#include <stdio.h>

int main(void) {
    printf("%zu\n", sizeof(unsigned int));
    return 0;
}
$ gcc -g -Wall -o main main.c
$ ./main
4
$ gcc --version
gcc (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$

1.png
2.png
3.png


编译器不一样,int的大小有可能就不一样
即使是同一个编译器,不同的编译选项也可能影响int的大小

gcc版本是 11.2.0,编译选项是-g -Wall
给出的结果是4个字节,那么unsigned int的范围就是0~4294967295,隨機種子的范围就是0~4294967295

tc的版本是3.0,编译选项用的默认的
给出的结果是2个字节,那么unsigned int的范围就是0~65535,隨機種子的范围就是0~65535


想知道隨機種子的范围,得先知道unsigned int的范围
想知道unsigned int的范围,得先知道unsigned int的大小
用sizeof运算符可以得到unsigned int的大小
知道了unsigned int的大小,就知道了unsigned int的范围
知道了unsigned int的范围,就知道了隨機種子的范围
就是这样

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
一隻太平洋睡鯊 + 5 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-17 10:19:34 | 显示全部楼层
要看你定义的变量类型,int整形的话就是32767。
1) 首先给srand()提供一个种子,它是一个unsigned int类型,其取值范围从0~65535;
2) 然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0到32767之间)

这些都是错误的,因为int整形不一定是32767, unsigned int类型取值范围也不一定是0~65535

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
一隻太平洋睡鯊 + 1 + 1 + 1 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-17 10:24:20 | 显示全部楼层
人造人 发表于 2022-5-17 10:19
要看你定义的变量类型,int整形的话就是32767。
1) 首先给srand()提供一个种子,它是一个unsigned int类型 ...
编译器不一样,int的大小有可能就不一样
即使是同一个编译器,不同的编译选项也可能影响int的大小

這麼說來,隨機種子的內容,不是由C語言本身決定,而是由編譯器來決定的?
即使視同一個數值的隨機種子(比如srand(1))
也有可能因為編譯器的不同,而呈現不一樣的算法嗎?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-17 10:25:52 | 显示全部楼层
rand()会返回一随机数值,范围在0至RAND_MAX 间。返回0至RAND_MAX之间的随机数值,RAND_MAX定义在stdlib.h,(其值至少为32767),运算的结果是一个不定的数,要看你定义的变量类型,int整形的话就是32767。 在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。一般用for语句来设置种子的个数。具体见下面的例子。
$ cat main.c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    printf("%u\n", RAND_MAX);
    return 0;
}
$ gcc -g -Wall -o main main.c
$ ./main
2147483647
$

1.png
2.png


评分

参与人数 1贡献 +1 收起 理由
一隻太平洋睡鯊 + 1 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-17 10:40:05 | 显示全部楼层    本楼为最佳答案   
一隻太平洋睡鯊 发表于 2022-5-17 10:24
這麼說來,隨機種子的內容,不是由C語言本身決定,而是由編譯器來決定的?
即使視同一個數值的隨機種 ...

這麼說來,隨機種子的內容,不是由C語言本身決定,而是由編譯器來決定的?
C語言标准没有规定int的大小,int的大小是由编译器的作者决定的

即使視同一個數值的隨機種子(比如srand(1))
也有可能因為編譯器的不同,而呈現不一樣的算法嗎?
这我就不知道了,我没有研究过这部分的内容
就算是随机算法一样,隨機種子的范围不一样,我想给出的结果应该也是不一样的
$ cat main.c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    srand(1);
    for(size_t i = 0; i < 10; ++i) {
        printf("%d\n", rand());
    }
    return 0;
}
$ gcc -g -Wall -o main main.c
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ clang -g -Wall -o main main.c
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$ ./main
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
$

1.png
2.png

评分

参与人数 2荣誉 +11 鱼币 +11 贡献 +9 收起 理由
Twilight6 + 6 + 6 + 6 鱼C有你更精彩^_^
一隻太平洋睡鯊 + 5 + 5 + 3 看來要理解這方面還需要更深入,對新手來說.

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-17 16:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表