一隻太平洋睡鯊 发表于 2022-5-16 21:51:09

隨機數種子的範圍

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

在前一個問題帖
收到了這個答覆
https://www.zhihu.com/question/380583678#:~:text=%E5%BA%95%E5%B1%82%E4%BD%BF%E7%94%A8C%E8%AF%AD%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-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
$

人造人 发表于 2022-5-16 22:08:58

tc给出的结果是
int 是 2
long 是 4
标准只规定了char是一个字节,其他的都没有规定



一隻太平洋睡鯊 发表于 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)的範圍不一樣?

人造人 发表于 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运算符可以得到其他类型的大小

人造人 发表于 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
$

人造人 发表于 2022-5-16 23:15:50



一隻太平洋睡鯊 发表于 2022-5-17 09:50:00

人造人 发表于 2022-5-16 23:08
字節=位元,应该是这样的,我们这边叫字节,你们那边应该就是位元
1个字节是8位,2^8(2的8次方)是256, ...

所以隨機種子是沒有範圍的?
任何4294967295以內的正整數都能夠放進srand()裡面?

人造人 发表于 2022-5-17 09:54:49

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

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

一隻太平洋睡鯊 发表于 2022-5-17 10:01:13

人造人 发表于 2022-5-17 09:54
有范围,范围就是unsigned int的范围
sizeof(unsigned int) 得到 unsigned int的大小
知道了unsigned i ...

我用了這個代碼,輸出是4,就是0~4294967295?
所以我開頭放的那個網站裡面寫的是錯的?

人造人 发表于 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.

$






编译器不一样,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的范围,就知道了隨機種子的范围
就是这样

人造人 发表于 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

一隻太平洋睡鯊 发表于 2022-5-17 10:24:20

人造人 发表于 2022-5-17 10:19
要看你定义的变量类型,int整形的话就是32767。
1) 首先给srand()提供一个种子,它是一个unsigned int类型 ...

编译器不一样,int的大小有可能就不一样
即使是同一个编译器,不同的编译选项也可能影响int的大小
這麼說來,隨機種子的內容,不是由C語言本身決定,而是由編譯器來決定的?
即使視同一個數值的隨機種子(比如srand(1))
也有可能因為編譯器的不同,而呈現不一樣的算法嗎?

人造人 发表于 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
$





人造人 发表于 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]
查看完整版本: 隨機數種子的範圍