Shop OBEX P1 Docs P2 Docs Learn Events
Random Number Problem — Parallax Forums

Random Number Problem

kt88seampkt88seamp Posts: 112
edited 2010-03-23 12:35 in Propeller 1
I am trying to set my dimmer object to a random brightness. The dimmer works by passing it a parameter of the number of clock cycles to wait to fire the triac. The range is 80000 (maximum brightness) to 640000 (minimum brightness). I am performing the calculation:

number := (RND.Random // 560000) + 80000

This does not work with my dimmer as the light almost never lights at all. The dimmer works. So it must be the algorithm generating the incorrect values or something fluky with spin. What algorithm will do the trick (a range from minimum to maximum)?

The program files are attached.

Comments

  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-03-22 23:48
    The random number generator seems to produce a number from 0 to $FFFF_FFFF so for most of the values it can produce your equation will produce values that are out of range.

    So you need to scale it such that when the random number is $FFFF_FFFF your equation gives 640000 and when zero it gives 80000. Something like this:

    number = (random/$FFFF_FFFF)*560000 + 80_000

    So if random was $FFFF_FFFF then it would give (1)*560000 + 80_000 = 640_000 and when random = 0, it would give just 80_000

    Re-writing this so we don't get overflows etc, then the divide by $FFFF_FFFF and multiply by 560_000 is the same as just dividing by 7669 so you get:

    number := (rand/7669) + 80_000

    Graham
  • kt88seampkt88seamp Posts: 112
    edited 2010-03-23 01:05
    I tried that and it unfortunately does not work. I played around with some other numbers and they too do not work. Are you sure that algorithm too will produce the right results?

    Posted is the new test program.
  • kuronekokuroneko Posts: 3,623
    edited 2010-03-23 01:12
    kt88seamp said...
    number := (RND.Random // 560000) + 80000
    This suffers from signed-ness. If RND.Random is negative (in SPIN terms) your result may become negative (i.e. out of range). As a quick fix try

    (RND.Random >> 1 // 560000) + 80000
    
  • kt88seampkt88seamp Posts: 112
    edited 2010-03-23 01:20
    You were right, it is signed VS unsigned. My device is now merrily producing random brightnesses. Does shifting over the bit make the random number generator produce all positive numbers?
  • kuronekokuroneko Posts: 3,623
    edited 2010-03-23 01:26
    kt88seamp said...
    Does shifting over the bit make the random number generator produce all positive numbers?
    Yes, bit 31 is the sign bit. By shifting the value right by 1 said bit is set to zero making the number positive. Minor drawback, you lose some resolution as you effectively half the random number range.

    Edit: the random number generator continues to produce negative numbers, we just tweak the result a bit.
  • kt88seampkt88seamp Posts: 112
    edited 2010-03-23 01:57
    If there any way of generating unsigned random values?
  • kt88seampkt88seamp Posts: 112
    edited 2010-03-23 02:31
    Better yet, my application would be better off bring capable of generating negative numbers too. So how would you compute the 80000 to 640000 range while assuming negative numbers are also being generated?
  • kuronekokuroneko Posts: 3,623
    edited 2010-03-23 02:36
    kt88seamp said...
    So how would you compute the 80000 to 640000 range while assuming negative numbers are also being generated?
    What about this?

    ||(RND.Random // 560000) + 80000
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-03-23 02:38
    The other issue (and potentially the bigger one) is that your perception of brightness will not be linear but that the distribution of the random numbers you're using is uniform. So the apparent brightness will appear to be weighted, even though the levels going to your controller are not.

    -Phil
  • kt88seampkt88seamp Posts: 112
    edited 2010-03-23 02:48
    The brightness always changes to a different perceptible level each time a new brightness is generated. I can always tweak the numbers if I want a non-uniform brightness.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-03-23 03:02
    Yes, but my point is that the perceived brightness is probably already non-uniform when driven with uniform random variates. To make it uniform, the numbers driving it have to be non-uniform.

    -Phil
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-03-23 12:35
    You could also use >>1 or || on the equation that I listed but kuroneko's looks good. I wasn't thinking about what // actually did when I first looked at your attempt.

    If you wanted to shape the response then I guess you could implement a sort of divider based on a look up table. For example for a range of values with a high weighting you might only need to generate one of two of them before actually using the value, for lower weightings you might need to generate 100's of them before actually using them. Your code would create random values until one of the "dividers" had reached its total and then use that value. I assume you can create random values a lot quicker than you need to use them.

    Graham
Sign In or Register to comment.