随机数生成器和4字节vs. 8字节整数的溢出 [英] Overflow in a random number generator and 4-byte vs. 8-byte integers

查看:87
本文介绍了随机数生成器和4字节vs. 8字节整数的溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

著名的线性同余随机数生成器,也称为最小标准使用公式

The famous linear congruential random number generator also known as minimal standard use formula

x(i+1)=16807*x(i) mod (2^31-1)

我想使用Fortran来实现.

I want to implement this using Fortran.

但是,正如数字食谱"所指出的那样,使用默认的Integer类型(32位)直接实现该公式将导致 16807 * x(i)溢出.

However, as pointed out by "Numerical Recipes", directly implement the formula with default Integer type (32bit) will cause 16807*x(i) to overflow.

因此,本书推荐Schrage的算法基于m的近似因式分解.仍然可以使用默认整数类型来实现此方法.

So the book recommend Schrage’s algorithm is based on an approximate factorization of m. This method can still implemented with default integer type.

但是,我想知道fortran实际上具有 Integer(8)类型,其范围是 -9,223,372,036,854,775,808 9,223,372,036,854,775,807 ,它比 16807 * x(i)是.

However, I am wondering fortran actually has Integer(8) type whose range is -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 which is much bigger than 16807*x(i) could be.

但书甚至说了以下一句话

but the book even said the following sentence

不可能直接实现公式(7.1.2)和(7.1.3)用高级语言表示,因为a和m − 1的乘积超过了一个32位整数的最大值.

It is not possible to implement equations (7.1.2) and (7.1.3) directly in a high-level language, since the product of a and m − 1 exceeds the maximum value for a 32-bit integer.

那么为什么我们不能只使用 Integer(8)类型直接实现公式?

So why can't we just use Integer(8) type to implement the formula directly?

推荐答案

是否可以使用8字节整数取决于您的编译器和系统.您可以使用 selected_int_kind 方法来获得一种具有一定范围的int.该代码可在我的64位计算机上编译并正常运行:

Whether or not you can have 8-byte integers depends on your compiler and your system. You can use the selected_int_kindmethod to get a kind of int that has a certain range. This code compiles on my 64 bit computer and works fine:

program ran
    implicit none
    integer, parameter :: i8 = selected_int_kind(R=18)
    integer(kind=i8) :: x
    integer :: i
    x = 100
    do i = 1, 100
        x = my_rand(x)
        write(*, *) x
    end do

    contains
        function my_rand(x)
            implicit none
            integer(kind=i8), intent(in) :: x
            integer(kind=i8) :: my_rand
            my_rand = mod(16807_i8 * x, 2_i8**31 - 1)
        end function my_rand
end program ran

这篇关于随机数生成器和4字节vs. 8字节整数的溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆