下面是从一个开放源码项目的rand()复制的,它使用LCG
rand_next = rand_next * 1103515245L + 12345L; //unsigned long rand_next经典的LCG是:
Next = (Next *a+ c)
很明显,这里M是2^32。
让我困惑的是rand_next * 1103515245L,我很确定会发生溢出!我看了几个rand()实现,除了使用不同的a和c之外,都采用这种方式。
溢出有害吗?如果不是为什么?
谢谢
发布于 2013-06-21 03:09:15
将signed long与unsigned long相乘。因此,*的两个操作数具有相同的整数转换秩。在这种情况下,适用以下规则(C++11,第5 /9节,第5项,第3项):
..。如果具有无符号整数类型的操作数的秩大于或等于另一个操作数类型的秩,则具有符号整数类型的操作数将转换为无符号整数类型的操作数类型。
因此,在计算乘法之前,这两个操作数都被隐式转换为unsigned long。因此,您将得到无符号算术和无符号结果,并且同样的规则同样适用于加法操作。
对于无符号的整数溢出是很好的定义(请参阅宗镇丽的答案,它已经被详细地扩展了),所以没有问题。
关于C(相对于C++),C11在第6.3.1.8/1节中有一条相同的规则:
..。如果具有无符号整数类型的操作数的秩大于或等于另一个操作数类型的秩,则带符号整数类型的操作数转换为无符号整数类型的操作数类型。
https://stackoverflow.com/questions/17226998
复制相似问题