summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2020-04-15 00:52:08 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2020-09-07 20:08:01 +0900
commitd6ec0ef59b4c7c95beaad09f77cb5f86a0901b97 (patch)
tree66d692d6abe2f2bb3c7c620544ba266b578d7909
parentc449b9b02f63cf8268a0eb9639a43caf4598996d (diff)
Added `get_real` interface
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3024
-rw-r--r--ext/-test-/random/loop.c10
-rw-r--r--include/ruby/random.h2
-rw-r--r--random.c1
-rw-r--r--test/-ext-/test_random.rb7
4 files changed, 20 insertions, 0 deletions
diff --git a/ext/-test-/random/loop.c b/ext/-test-/random/loop.c
index 92af1a9b18..246a1f5fd9 100644
--- a/ext/-test-/random/loop.c
+++ b/ext/-test-/random/loop.c
@@ -7,10 +7,13 @@ typedef struct {
uint32_t num, idx, *buf;
} rand_loop_t;
+static double loop_get_real(rb_random_t *rnd, int excl);
+
RB_RANDOM_INTERFACE_DECLARE(loop)
static const rb_random_interface_t random_loop_if = {
32,
RB_RANDOM_INTERFACE_DEFINE(loop)
+ loop_get_real,
};
static size_t
@@ -91,6 +94,13 @@ loop_get_int32(rb_random_t *rnd)
return 0;
}
+static double
+loop_get_real(rb_random_t *rnd, int excl)
+{
+ uint32_t a = loop_get_int32(rnd);
+ return ldexp(a, -16);
+}
+
void
Init_random_loop(VALUE mod, VALUE base)
{
diff --git a/include/ruby/random.h b/include/ruby/random.h
index 21b6796a3e..4dd12d5f19 100644
--- a/include/ruby/random.h
+++ b/include/ruby/random.h
@@ -28,12 +28,14 @@ typedef struct {
typedef void rb_random_init_func(rb_random_t *, const uint32_t *, size_t);
typedef unsigned int rb_random_get_int32_func(rb_random_t *);
typedef void rb_random_get_bytes_func(rb_random_t *, void *, size_t);
+typedef double rb_random_get_real_func(rb_random_t *, int);
typedef struct {
size_t default_seed_bits;
rb_random_init_func *init;
rb_random_get_int32_func *get_int32;
rb_random_get_bytes_func *get_bytes;
+ rb_random_get_real_func *get_real;
} rb_random_interface_t;
#define rb_rand_if(obj) \
diff --git a/random.c b/random.c
index 3fef5cea3b..75f4dbaa21 100644
--- a/random.c
+++ b/random.c
@@ -989,6 +989,7 @@ random_real(VALUE obj, rb_random_t *rnd, int excl)
}
else {
const rb_random_interface_t *rng = try_rand_if(obj, rnd);
+ if (rng->get_real) return rng->get_real(rnd, excl);
a = random_int32(rng, rnd);
b = random_int32(rng, rnd);
}
diff --git a/test/-ext-/test_random.rb b/test/-ext-/test_random.rb
index da716c71c0..838e5d2f14 100644
--- a/test/-ext-/test_random.rb
+++ b/test/-ext-/test_random.rb
@@ -16,5 +16,12 @@ module TestRandomExt
rnd = Bug::Random::Loop.new(1)
assert_equal(1, rnd.rand(10))
end
+
+ def test_real
+ assert_equal(0.25, Bug::Random::Loop.new(1<<14).rand)
+ assert_equal(0.50, Bug::Random::Loop.new(2<<14).rand)
+ assert_equal(0.75, Bug::Random::Loop.new(3<<14).rand)
+ assert_equal(1.00, Bug::Random::Loop.new(4<<14).rand)
+ end
end
end