Reputation: 3959
When I compile mt19937ar.c, a pretty standard random number generator, I keep getting issues with a bit of code that I need from it.
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 */
}
}
Specifically, the error is with
mt[mti] =
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
I've tried casting it via
mt[mti] = (long unsigned int)
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
which really doesn't make sense to do but I'm just attempting something. This code is from 1997- figured someone would have caught this by now and fixed it. How can I solve this? Or get my compiler to stop crying about it?
Upvotes: 3
Views: 14980
Reputation: 6016
You need to change type of mti
to unsigned int
or unsigned long int
static unsigned int mti = N+1;
Because mti
will be promoted to unsigned long
in your given expression
Upvotes: 4
Reputation: 134336
I believe, the problem is in the below part of code
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
^
The first part, (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30))
will produce a result of type unsigned long
, and the mti
is of type int
.
As per the semantics of Additive operators, chapter §6.5.6
If both operands have arithmetic type, the usual arithmetic conversions are performed on them.
the RHS operand, mti
gets promoted to unsigned long
(from int
) , according to the rule mentioned in §6.3.1.8/p1
- 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.
which causes the warning.
Solution: You can make mti
an unsigned long
.
Upvotes: 0