无法解决 "warning: conversion to 'long unsigned int' from 'int'"

Cant solve "warning: conversion to 'long unsigned int' from 'int'"

当我编译 mt19937ar.c,一个非常标准的随机数生成器时,我总是遇到一些我需要的代码的问题。

In function 'init_genrand':

warning: conversion to 'long unsigned int' from 'int' may change the sign of the result

/* Period parameters */  
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */

static unsigned long mt[N]; /* the array for the state vector  */
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */

/* initializes mt[N] with a seed */
void init_genrand(unsigned long s)
{
    mt[0]= s & 0xffffffffUL;
    for (mti=1; mti<N; mti++) {
        mt[mti] = 
            (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 
        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
        /* In the previous versions, MSBs of the seed affect   */
        /* only MSBs of the array mt[].                        */
        /* 2002/01/09 modified by Makoto Matsumoto             */
        mt[mti] &= 0xffffffffUL;
        /* for >32 bit machines */
    }
}

具体错误是

mt[mti] = 
            (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);

我试过通过

投射它
mt[mti] = (long unsigned int)
            (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 

这确实没有意义,但我只是在尝试一些事情。这段代码来自 1997 年——估计现在有人会发现并修复它。我该如何解决这个问题?或者让我的编译器停止哭泣?

我相信,问题出在下面的代码部分

 (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
                                                   ^

第一部分 (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) 将产生 unsigned long 类型的结果,而 mtiint.

类型的结果

根据加法运算符的语义,章节 §6.5.6

If both operands have arithmetic type, the usual arithmetic conversions are performed on them.

根据 §6.3.1.8/p1

中提到的规则,

RHS 操作数 mti 被提升为 unsigned long(从 int

  • Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

导致警告。

解决方案:您可以将 mti 设为 unsigned long

您需要将 mti 的类型更改为 unsigned intunsigned long int

static unsigned int mti = N+1;

因为 mti 将在您给定的表达式中提升为 unsigned long