Handle RAND_MAX < 2^32 in get_random_gint64()

MacOSX, for example, sets RAND_MAX at 65535, which rather limits the
size of random gint64s on that platform.

Fixing this revealed some odd behavior in creating random interest rates,
so created a specific function for that with a somewhat more reasonable
approach.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@23493 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
John Ralls 2013-12-05 21:54:18 +00:00
parent 71654e984c
commit de3a6e3df2
3 changed files with 42 additions and 8 deletions

View File

@ -467,17 +467,23 @@ get_random_gnc_numeric(void)
* The loop is to "make sure" we get there. We might
* want to make this dependent on "deno" in the future.
*/
do
{
numer = get_random_gint64() / 1000000;
}
while ((numer >> 31) > 0x1FFFF);
numer = get_random_gint64 () % (2ULL << 48);
if (0 == numer) numer = 1;
/* Make sure we have a non-zero denominator */
if (0 == deno) deno = 1;
return gnc_numeric_create(numer, deno);
}
static gnc_numeric
get_random_rate (void)
{
/* Large rates blow up xaccSplitAssignToLot, so we clamp the rate
* at a smallish value */
gint64 numer = get_random_gint64 () % (2ULL << 24);
gint64 denom = 100LL;
return gnc_numeric_create (numer, denom);
}
/* ================================================================= */
/* Commodity stuff */
@ -1315,7 +1321,8 @@ get_random_split(QofBook *book, Account *acct, Transaction *trn)
xaccSplitGetAccount(ret)));
do
{
rate = gnc_numeric_abs(get_random_gnc_numeric());
/* Large rates blow up xaccSplitAssignLot */
rate = get_random_rate ();
amt = gnc_numeric_mul(val, rate,
GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
amt = gnc_numeric_convert(amt, denom, GNC_HOW_RND_ROUND_HALF_UP);

View File

@ -313,14 +313,40 @@ get_random_string(void)
return get_random_string_without (NULL);
}
gint32
get_random_gint32 (void)
{
gint32 ret = 0;
if (RAND_MAX > (1 << 15))
return rand ();
if (RAND_MAX > (1 << 7))
{
ret = rand ();
ret <<= 16;
ret += rand ();
return ret;
}
ret = rand ();
ret <<= 8;
ret += rand ();
ret <<= 8;
ret += rand ();
ret <<= 8;
ret += rand ();
return ret;
}
gint64
get_random_gint64(void)
{
gint64 ret = 0;
ret = rand();
ret = get_random_gint32 ();
ret <<= 32;
ret += rand();
ret += get_random_gint32 ();
return ret;
}

View File

@ -124,6 +124,7 @@ gchar get_random_character(void);
gchar* get_random_string(void);
gchar * get_random_string_length_in_range(int minlen, int maxlen);
gchar* get_random_string_without(const char *exclude_chars);
gint32 get_random_gint32 (void);
gint64 get_random_gint64(void);
double get_random_double(void);
const char* get_random_string_in_array(const char* str_list[]);