Hosted by uCoz
Функция, которая генерит RANDOM до 1,073,676,289

Автор: David Dennis david.dennis@paradise.net.nz
	    
	    ////////////////////////////////////////////////////////////////////
	// Function: f_BigRand
	//
	// Description:
	// This function uses 2 calls to Rand to generate
	// Random numbers for large
	// ranges. It breaks the range into blocks of 32767 (max range for
	// RAND function)
	// The limit of the function is 32767 blocks of 32767. 
	// It calls RAND to first determine which block, then calls 
	// RAND again to 
	// determine the number in the
	// selected block. To ensure even probability over the range where
	//  there are multiple blocks,
	// the same sub range is used for each block.
	// 
	// Argument al_range 
	// The upper limit of the range of random numbers you want returned.
	// The lower limit is always 1. The maximum value for 
	// the argument is 
	// 1,073,676,289 or 32767*32767.
	// 
	// Returns
	// A random number in the range 1 to al_range inclusive.
	// Or 0 if max range exceeded.
	//
	// Author: David Dennis
	////////////////////////////////////////////////////////////////////
	//
	// Revision History
	// 
	// ---------------------------------------------------------------
	// VERSION CHANGE ID WHO WHEN WHAT/WHY
	// ---------------------------------------------------------------
	// 6.30 8/4/00 Initial version.
	///////////////////////////////////////////////////////////////////
	Long ll_Offset, ll_Return
	Integer li_Range, li_Blocks
	
	// Block size is set to 32767 as this is the maximum range
	// the RAND function can handle 
	Integer li_BlockSize = 32767
	
	IF al_range > 1073676289 THEN
		//Range is too big
		Return 0
	END IF
	
	//Determine The number of blocks
	li_Blocks = Truncate(al_range/li_BlockSize,0) 
	
	//Add an extra block to accommodate any remainder
	IF Mod(al_range, li_BlockSize) > 0 THEN
		li_Blocks = li_Blocks + 1
	END IF
	
	// Improve efficiency for ranges less than Block Size
	// where there is only one block 
	IF al_range < li_BlockSize THEN
		li_Range = al_range
	ELSE
		li_Range = li_BlockSize
	END IF
	
	ll_Return = 0
	
	// Loop until the value is in range. 
	// If the value is not in range, calculate the 
	// Offset again to ensure even probability 
	DO UNTIL (ll_Return > 0) And (ll_Return <= al_Range)
		// Calculate a Random Offset using the number
		// of blocks as the range. 
		// Offsets will range from [0 to (li_Blocks - 1)*BlockSize]
		// in increments of BlockSize
		ll_Offset = (Rand(li_Blocks) - 1) * li_BlockSize
	
		//Main Calculation
		ll_Return = ll_Offset + Rand(li_Range)
	LOOP
	
	Return ll_Return