Problem with constrain()

Code:

#include <Tlc5940.h>
int i,j=1;

void setup() {
  Tlc.init() ;
  Serial.begin(9600);
}

void loop() {
  int i,j;
  Tlc.set(i=random(0,47),j=constrain(random(0,30)-3,0,100));
  Serial.print(i);Serial.print(':');Serial.println(j);
  Tlc.update();
  delay(40);
}

Serial monitor output:

28:5
9:0
10:16
31:-1
6:16
34:16
4:0
39:22
38:4
23:16
16:-1
27:2
11:0
31:20

Why the "-1" ?? (It makes the LED full ON which I do not want)

Loosing my mind here... it gets worse. Changing the important line to

  Tlc.set(i=random(0,47),j=constrain(random(0,30)*20,0,100));

I get output

23:100
44:100
16:100
8:80
3:320
43:100
26:100
#include <Tlc5940.h>
int i,j=1;

void setup() {
  Tlc.init() ;
  Serial.begin(9600);
}

void loop() {
  int i,j,t;
  i=random(0,47);
  t=random(0,30)-3;
  j=constrain(t,0,100);
  Tlc.set(i,j);
  Serial.print(i);Serial.print(':');Serial.println(j);
  Tlc.update();
  delay(40);
}

...produces?

FYI, the two global variables are excised by the linker.

#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

A good example of why C macros are dangerous.
When you do "constrain(random(0,30)-3, 0, 100)" it expands to:

(random(0,30)-3 < 0 ? 0 : ((random(0,30)-3) > 100 ? 100 : random(0,30)-3)

It calls random (up to) three times, and if the first two are in-range, it will return the third random number.

Grr. This should probably be a c++ template function; I hear that they're just the thing for fixing this!

Of course.

Thanks.

westfw:
Grr. This should probably be a c++ template function; I hear that they're just the thing for fixing this!

There is at least one problem with the template version. Just a minute ... I'll see if I can find the thread ...

Found it...
http://forum.arduino.cc/index.php/topic,84364.0

This is the form that seems to work the best...
http://forum.arduino.cc/index.php/topic,84364.msg640438.html#msg640438

My notes...
http://forum.arduino.cc//index.php?topic=84364.msg808183#msg808183