无法解决“warning: conversion to 'long unsigned int' from 'int'”问题

3
当我编译一个很常见的随机数生成器mt19937ar.c时,我一直遇到需要从中获取的一些代码问题。

在函数“init_genrand”中:

警告:从'int'转换为'long unsigned int'可能会改变结果的符号。

/* 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年,我想有人应该已经发现并修复了它。我该如何解决这个问题?或者让我的编译器不再抱怨它?


@SouravGhosh 30UL 是什么意思? - 8protons
@8protons 他的意思是 (mt[mti-1] >> 30 - Danh
@Danh 哦,好的,还是只有转换警告 -_- - 8protons
@Danh问题出在整数提升上,而不是结果。 - Sourav Ghosh
@SouravGhosh 我认为那不是问题,因为楼主说他仍然收到了那个警告。 - Danh
显示剩余6条评论
2个回答

4

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

static unsigned int mti = N+1;

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


0

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

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

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

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

如果两个操作数都具有算术类型,则对它们执行通常的算术转换。

RHS操作数mti根据§6.3.1.8/p1中提到的规则被提升为unsigned long(从int),

  • 否则,如果具有无符号整数类型的操作数的等级大于或等于另一个操作数的类型的等级,则具有带符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型。

这导致了警告。

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


我按照你上一句话的指示去做了,但仍然收到相同的编译器警告。 - 8protons
@8protons 哦,我明白了,逻辑是一样的,但问题在于mti是一个整数。 - Sourav Ghosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接