bad code or a bug?

when I execute the following:

    randomSeed(analogRead(A0));
    long randomNum = random(-1*pow(2, 31),pow(2, 31)-1);  //get random number
    Serial.print("randomNum= ");
    Serial.println(randomNum, DEC);

I only get the following:

randomNum= -2147483648
randomNum= -2147483648
randomNum= -2147483648
randomNum= -2147483648
randomNum= -2147483648
randomNum= -2147483648
randomNum= -2147483648
randomNum= -2147483648
randomNum= -2147483648

So is this a bug or is it my coding? thank

try unsigned long

Does it work any better if you use integer calculations (1<<31) instead of floating point pow(2,31)?

-br

billroy:
Does it work any better if you use integer calculations (1<<31) instead of floating point pow(2,31)?

That gave all zeros.

This:

    long randomNum = random(-2147483648,2147483647);  //get random number

gives:

randomNum= -2147483648
randomNum= -2147483648
randomNum= -2147483648
randomNum= -2147483648

This works fine:

    int randomNum = random(-32768,32767);  //get random number

So I believe random only supports up to int and not long

   long randomNum = random(-2147483648,2147483647)

What if you do:

   long randomNum = random((long)-2147483648,(long)2147483647)

?

[quote author=James C4S link=topic=164590.msg1228777#msg1228777 date=1367711336]

   long randomNum = random(-2147483648,2147483647)

What if you do:

   long randomNum = random((long)-2147483648,(long)2147483647)

? [/quote]

I get the same number over and over again

I think this is the code that the library uses in WMath.cpp:

long random(long howbig)
{
  if (howbig == 0) {
    return 0;
  }
  return random() % howbig;
}

long random(long howsmall, long howbig)
{
  if (howsmall >= howbig) {
    return howsmall;
  }
  long diff = howbig - howsmall;
  return random(diff) + howsmall;
}

In which case diff=howbig-howsmall results in diff=-1. Then random(-1) calculates random()%(-1) which is zero. So it returns -2147483648 + -1 which is -2147483648.

The problem is that the range of signed 32-bit numbers is not symmetrical. +2147483648 can't be represented in 32 bits: -2147483648 = - (-2147483648)

Pete

el_supremo: I think this is the code that the library uses in WMath.cpp:

long random(long howbig)
{
  if (howbig == 0) {
    return 0;
  }
  return random() % howbig;
}

long random(long howsmall, long howbig) {  if (howsmall >= howbig) {    return howsmall;  }  long diff = howbig - howsmall;  return random(diff) + howsmall; }




In which case diff=howbig-howsmall results in diff=-1. Then random(-1) calculates random()%(-1) which is zero. So it returns
-2147483648 + -1
which is -2147483648.

The problem is that the range of signed 32-bit numbers is not symmetrical. +2147483648 can't be represented in 32 bits:
-2147483648 = - (-2147483648)

Pete

even this only produces all zeros:

    unsigned long randomNum = random(0,4294967295);

You're still using numbers that can't be represented as a signed 32-bit number. The compiler converts 4294967295 to -1.

A signed 32 bits number can represent the range -2147483648 to +2147483647

Pete

The key is the line:

long diff = howBig - howSmall;

The result of that operation must be a number that can be represented in a signed long. So the maximum "range" you can use is 2147483647.

long randomNum = random(-1073741823,1073741823);

Edit: Added signed to be more clear.

[quote author=James C4S link=topic=164590.msg1229332#msg1229332 date=1367760200] The result of that operation must be a number that can be represented in a long. So the maximum "range" you can use is 2147483647. [/quote]

That's the critical point, and what's especially significant is that it's a [u]signed[/u] long, meaning that it can only hold a 31 bit positive value. It looks like a bug to me - an unsigned long would be more appropriate IMO and would enable random(long, long) to cover the full range of 32-bit values.

if the A0 pin has been hardwired then randomSeed(analogRead(A0)) will always seed the pseudo-random number generator with the same value, so the random() function will always return the same value.

What happens if you move the

randomSeed(analogRead(A0))

to setup() (so it only gets run once) and leave the rest of the code

long randomNum = random(-1*pow(2, 31),pow(2, 31)-1);  //get random number
    Serial.print("randomNum= ");
    Serial.println(randomNum, DEC);

in loop()?

That should ensure that random() always returns a different number