randparkmiller.cpp revision 210e87cc03f92d54681b81a81cc1fdbd48a9d2c8
/* $Id$ */
/** @file
* IPRT - Random Numbers, Park-Miller Pseudo Random.
*/
/*
* Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <iprt/asm-math.h>
{
/*
* Park-Miller random number generator:
* X2 = X1 * g mod n.
*
* We use the constants suggested by Park and Miller:
* n = 2^31 - 1 = INT32_MAX
* g = 7^5 = 16807
*
* This will produce numbers in the range [0..INT32_MAX-1], which is
* almost 31-bits. We'll ignore the missing number for now and settle
* for just filling in the missing bit instead (the caller does this).
*/
if (!x1)
x1 = 20080806;
/*uint32_t x2 = ((uint64_t)x1 * 16807) % INT32_MAX;*/
}
/** @copydoc RTRANDINT::pfnGetU32 */
static DECLCALLBACK(uint32_t) rtRandParkMillerGetU32(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last)
{
if (offLast == UINT32_MAX)
{
/* 30 + 2 bit (make up for the missing INT32_MAX value) */
{
}
off >>= 1;
}
/* The exact range. */
{
/* Requested 23 or fewer bits, just lose the lower bit. */
off >>= 1;
}
else
{
/*
* 30 + 6 bits.
*/
{
}
off64 >>= 1;
}
}
/** @copydoc RTRANDINT::pfnSeed */
{
return VINF_SUCCESS;
}
/** @copydoc RTRANDINT::pfnSaveState */
static DECLCALLBACK(int) rtRandParkMillerSaveState(PRTRANDINT pThis, char *pszState, size_t *pcbState)
{
if (*pcbState < RTRAND_PARKMILLER_STATE_SIZE)
{
return VERR_BUFFER_OVERFLOW;
}
return VINF_SUCCESS;
}
/** @copydoc RTRANDINT::pfnRestoreState */
{
/* marker */
if ( pszState[0] != 'P'
return VERR_PARSE_ERROR;
pszState += 3;
/* u32Ctx */
if ( rc != VWRN_TRAILING_CHARS
|| *pszNext != ',')
return VERR_PARSE_ERROR;
/* u32Bits */
if ( rc != VWRN_TRAILING_CHARS
|| *pszNext != ',')
return VERR_PARSE_ERROR;
/* cBits */
if ( rc != VWRN_TRAILING_CHARS
|| *pszNext != ';'
return VERR_PARSE_ERROR;
/* commit */
return VINF_SUCCESS;
}
{
if (!pThis)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
}