Menu

random number with range

Help
viscomjim
2015-03-07
2015-03-12
  • viscomjim

    viscomjim - 2015-03-07

    Looking for a way to create a random number between a low and high range but seem limited to 0 - 255. Using this right now, but am not sure if there is a better way... Is there any way to get a random number that has a range wider than 0 - 255, like maybe 1 to 2000? Any and all input is greatly appreciated.

    #chip 12f1840,32
    
    #DEFINE USART_BAUD_RATE 9600
    #DEFINE USART_BLOCKING
    
    Dir PORTA.4 In
    
    DO
    RANDOMIZE READAD(AN3) 'SEED USING FLOATING A2D PIN - not the best practice I know...
    RP = RANDNUM (12, 144) 'RANGE FROM 12 TO 144
    HSERPRINT RP
    HSERPRINTCRLF
    WAIT 100 MS
    LOOP
    
    
    FUNCTION RANDNUM (MINVAL, MAXVAL)
    RN = RANDOM
    AA = MAXVAL - MINVAL + 1
    BB = RN MOD AA
    RANDNUM = MINVAL + BB
    END FUNCTION
    
     
  • Jacques Nilo

    Jacques Nilo - 2015-03-10

    To specify the range of your random number the modulo operator is your friend.

     temp = random%50 + offset
    

    will give you a peuso random number in the [offset;offset+50] range.
    Now if you want a higher random number than 255 you have to use a RNG of your own since the default random function in GCBASIC only return a byte variable.
    I am not an expert neither in RNG nor in C but I came across the following link describing the way to generate a random number using the Marsaglia MWC approach. Marsaglia's original post is here
    I guess the translation in GCBASIC should be something like:

    function randmwc() as long
    ; Marsaglia's MWC RNG
      Set STATUS.C Off
      Rotate m_z right
      m_z = 36969 * (m_z & 65535) + m_z
      Set STATUS.C Off
      Rotate m_w right
      m_w = 18000 * (m_w & 65535) + m_w
      Set STATUS.C Off
      Rotate m_z left
      randmwc = m_z + m_w
    end function
    

    m_z and m_w have to be declared as long in main and initialized with non zero value
    This function should (but cannot guarantee 100%...)return a long pseudo random number and you could then apply the modulo trick.
    Follows a test program to generate a random comprised betwenn 0 and 5000.
    Jacques

    #chip 16F690, 8
    #config FOSC_INTOSC, WDTE_OFF
    
    ;Defines (Constants)                
    #define LCD_IO 4
    #define LCD_RS PORTC.5
    #define LCD_NO_RW
    #define LCD_Enable PORTC.4
    #define LCD_DB4 PORTC.0
    #define LCD_DB5 PORTC.1
    #define LCD_DB6 PORTC.2
    #define LCD_DB7 PORTC.3
    
    function randmwc() as long
    ; Marsaglia's MWC algorithm
      Set STATUS.C Off
      Rotate m_z right
      m_z = 36969 * (m_z & 65535) + m_z
      Set STATUS.C Off
      Rotate m_w right
      m_w = 18000 * (m_w & 65535) + m_w
      Set STATUS.C Off
      Rotate m_z left
      randmwc = m_z + m_w
    end function
    
    ; Initialize m_z & m-w with seeds proposed by Marsaglia
    ' Better random initizialisation could be generated through timers
    dim m_z,m_w as long
    m_z=362436069
    m_w=521288629
    repeat 100
      cls
      print randmwc()%5000
      wait 500 ms
    end repeat
    cls
    
     

    Last edit: Jacques Nilo 2015-03-11
  • viscomjim

    viscomjim - 2015-03-12

    Hi Jacques, quick question.

    What does the "Set STATUS.C Off" do in this.

    I will have to give this a whirl. Thanks for your help!!!

     
  • Jacques Nilo

    Jacques Nilo - 2015-03-12

    Excerpt from Hugh's following thread: "In GCBASIC you need to clear status bit C to stop it from getting rotated into the end of the variable."

     

    Last edit: Jacques Nilo 2015-03-12

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.