summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--random.c28
2 files changed, 24 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 56c54b4..ec781a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Feb 24 21:03:04 2016 Tanaka Akira <akr@fsij.org>
+
+ * random.c (limited_rand): Add a specialized path for the limit fits
+ in 32 bit.
+
Tue Feb 23 21:52:24 2016 Martin Duerst <duerst@it.aoyama.ac.jp>
* enc/unicode/case-folding.rb, casefold.h: Outputting actual titlecase
diff --git a/random.c b/random.c
index 936121f..7796d34 100644
--- a/random.c
+++ b/random.c
@@ -826,21 +826,31 @@ static unsigned long
limited_rand(struct MT *mt, unsigned long limit)
{
/* mt must be initialized */
- int i;
unsigned long val, mask;
if (!limit) return 0;
mask = make_mask(limit);
- retry:
- val = 0;
- for (i = SIZEOF_LONG/SIZEOF_INT32-1; 0 <= i; i--) {
- if ((mask >> (i * 32)) & 0xffffffff) {
- val |= (unsigned long)genrand_int32(mt) << (i * 32);
- val &= mask;
- if (limit < val)
- goto retry;
+
+#if 4 < SIZEOF_LONG
+ if (0xffffffff < limit) {
+ int i;
+ retry:
+ val = 0;
+ for (i = SIZEOF_LONG/SIZEOF_INT32-1; 0 <= i; i--) {
+ if ((mask >> (i * 32)) & 0xffffffff) {
+ val |= (unsigned long)genrand_int32(mt) << (i * 32);
+ val &= mask;
+ if (limit < val)
+ goto retry;
+ }
}
+ return val;
}
+#endif
+
+ do {
+ val = genrand_int32(mt) & mask;
+ } while (limit < val);
return val;
}