Repository: c-cube/qcheck (ocaml)

Issue:

Pull request description:
Add an exponential generator
This PR adds an exponential generator to both QCheck and QCheck2, using a mapping from a uniform [0;1] distribution
https://en.wikipedia.org/wiki/Relationships_among_probability_distributions
https://en.wikipedia.org/wiki/Exponential_distribution#Random_variate_generation

All of them takes a mean/average parameter, e.g., `exponential 10.`, and results in a distribution where samples approximate that mean/average:
```
+++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

stats dist:
  num: 5000, avg: 9.56, stddev: 9.91, median 7, min 0, max 89
    0..  4: #######################################################        1934
    5..  9: ##################################                             1202
   10.. 14: ####################                                            727
   15.. 19: ############                                                    452
   20.. 24: ########                                                        284
   25.. 29: ####                                                            164
   30.. 34: ##                                                              103
   35.. 39: #                                                                51
   40.. 44:                                                                  26
   45.. 49:                                                                  24
   50.. 54:                                                                  15
   55.. 59:                                                                   7
   60.. 64:                                                                   3
   65.. 69:                                                                   2
   70.. 74:                                                                   2
   75.. 79:                                                                   1
   80.. 84:                                                                   1
   85.. 89:                                                                   2
   90.. 94:                                                                   0
   95.. 99:                                                                   0
```
We've found the combinator useful in QCheck-STM to generate `cmd` lists of a reasonable length ocaml-multicore/multicoretests#472 but thought the combinator could be more generally useful.

We may even consider switching our `list`, `array`, `string`, and `bytes` generators to output lengths following such an exponential distribution, but that will be for another day - and PR...

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 39f955f..bb23e9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 ## NEXT RELEASE
 
+- Add `exponential` generator to `QCheck`, `QCheck.Gen`, and `QCheck2.Gen`
 - Add `Shrink.bool` and use it in `QCheck.bool`
 - Remove unread `fun_gen` field from `QCheck2`'s `fun_repr_tbl` type
   thereby silencing a compiler warning
diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml
index 0784084..bf5b627 100644
--- a/src/core/QCheck.ml
+++ b/src/core/QCheck.ml
@@ -181,6 +181,12 @@ module Gen = struct
 
   let (--.) = float_range
 
+  let exponential mean =
+    if Float.is_nan mean then invalid_arg "Gen.exponential";
+    let unit_gen = float_bound_inclusive 1.0 in
+    map (fun p -> -. mean *. (log p)) unit_gen
+    (* See https://en.wikipedia.org/wiki/Relationships_among_probability_distributions *)
+
   let neg_int st = -(nat st)
 
   let option ?(ratio = 0.85) f st =
@@ -1103,6 +1109,8 @@ let float_bound_exclusive bound =
 
 let float_range low high = make_scalar ~print:string_of_float (Gen.float_range low high)
 
+let exponential mean = make_scalar ~print:Print.float (Gen.exponential mean)
+
 let int = make_int Gen.int
 let int_bound n = make_int (Gen.int_bound n)
 let int_range a b = make_int (Gen.int_range a b)
diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli
index ea3fcd2..7d123d3 100644
--- a/src/core/QCheck.mli
+++ b/src/core/QCheck.mli
@@ -267,6 +267,12 @@ module Gen : sig
   (** Synonym for [float_range]
       @since 0.11 *)
 
+  val exponential : float -> float t
+  (** [exponential m] generates floating-point numbers following an exponential
+      distribution with a mean of [m].
+      @raise Invalid_argument if [m] is NaN.
+      @since NEXT_VERSION *)
+
   val nat : int t (** Generates small natural numbers. *)
 
   val big_nat : int t
@@ -1233,6 +1239,12 @@ val float_range : float -> float -> float arbitrary
     @raise Invalid_argument if [low > high] or if the range is larger than [max_float].
     @since 0.11 *)
 
+val exponential : float -> float arbitrary
+(** [exponential m] generates floating-point numbers following an exponential
+    distribution with a mean of [m].
+    @raise Invalid_argument if [m] is NaN.
+    @since NEXT_VERSION *)
+
 val int : int arbitrary
 (** Int generator. Uniformly distributed. *)
 
diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml
index ea315bf..b4e8560 100644
--- a/src/core/QCheck2.ml
+++ b/src/core/QCheck2.ml
@@ -369,6 +369,12 @@ module Gen = struct
 
   let (--.) low high = float_range ?origin:None low high
 
+  let exponential (mean : float) =
+    if Float.is_nan mean then invalid_arg "Gen.exponential";
+    let unit_gen = float_bound_inclusive 1.0 in
+    map (fun p -> -. mean *. (log p)) unit_gen
+    (* See https://en.wikipedia.org/wiki/Relationships_among_probability_distributions *)
+
   let neg_int : int t = nat >|= Int.neg
 
   (** [option gen] shrinks towards [None] then towards shrinks of [gen]. *)
diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli
index ceed40e..c6cae16 100644
--- a/src/core/QCheck2.mli
+++ b/src/core/QCheck2.mli
@@ -516,6 +516,14 @@ module Gen : sig
 
       @since 0.11 *)
 
+  val exponential : float -> float t
+  (** [exponential m] generates floating-point numbers following an exponential
+      distribution with a mean of [m].
+
+      @raise Invalid_argument if [m] is NaN.
+
+      @since NEXT_VERSION *)
+
   val char_range : ?origin:char -> char -> char -> char t
   (** [char_range ?origin low high] generates chars between [low] and [high], inclusive.
       Example: [char_range 'a' 'z'] for all lower case ASCII letters.


Test patch:
diff --git a/test/core/QCheck2_expect_test.expected.ocaml4.32 b/test/core/QCheck2_expect_test.expected.ocaml4.32
index 126bcd4..e25a26e 100644
--- a/test/core/QCheck2_expect_test.expected.ocaml4.32
+++ b/test/core/QCheck2_expect_test.expected.ocaml4.32
@@ -1395,9 +1395,59 @@ stats dist:
     751619287..  858993469:                                                                   0
     858993470..  966367652:                                                                   0
     966367653.. 1073741823: #################                                               189
+
++++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: 9.56, stddev: 9.91, median 7, min 0, max 89
+    0..  4: #######################################################        1934
+    5..  9: ##################################                             1202
+   10.. 14: ####################                                            727
+   15.. 19: ############                                                    452
+   20.. 24: ########                                                        284
+   25.. 29: ####                                                            164
+   30.. 34: ##                                                              103
+   35.. 39: #                                                                51
+   40.. 44:                                                                  26
+   45.. 49:                                                                  24
+   50.. 54:                                                                  15
+   55.. 59:                                                                   7
+   60.. 64:                                                                   3
+   65.. 69:                                                                   2
+   70.. 74:                                                                   2
+   75.. 79:                                                                   1
+   80.. 84:                                                                   1
+   85.. 89:                                                                   2
+   90.. 94:                                                                   0
+   95.. 99:                                                                   0
+
++++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: -9.56, stddev: 9.91, median -7, min -89, max 0
+  -89..-85:                                                                   2
+  -84..-80:                                                                   1
+  -79..-75:                                                                   1
+  -74..-70:                                                                   2
+  -69..-65:                                                                   2
+  -64..-60:                                                                   3
+  -59..-55:                                                                   7
+  -54..-50:                                                                  15
+  -49..-45:                                                                  24
+  -44..-40:                                                                  26
+  -39..-35: #                                                                51
+  -34..-30: ##                                                              103
+  -29..-25: ####                                                            164
+  -24..-20: ########                                                        284
+  -19..-15: ############                                                    452
+  -14..-10: ####################                                            727
+   -9.. -5: ##################################                             1202
+   -4..  0: #######################################################        1934
+    1..  5:                                                                   0
+    6.. 10:                                                                   0
 ================================================================================
 1 warning(s)
-failure (64 tests failed, 3 tests errored, ran 141 tests)
+failure (64 tests failed, 3 tests errored, ran 143 tests)
 random seed: 153870556
 
 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/test/core/QCheck2_expect_test.expected.ocaml4.64 b/test/core/QCheck2_expect_test.expected.ocaml4.64
index b1d73a6..9f2b7df 100644
--- a/test/core/QCheck2_expect_test.expected.ocaml4.64
+++ b/test/core/QCheck2_expect_test.expected.ocaml4.64
@@ -1459,9 +1459,59 @@ stats dist:
    3228180212899171968.. 3689348814741910783:                                                                   0
    3689348814741910784.. 4150517416584649599:                                                                   0
    4150517416584649600.. 4611686018427387903: #################                                               189
+
++++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: 9.56, stddev: 9.91, median 7, min 0, max 89
+    0..  4: #######################################################        1934
+    5..  9: ##################################                             1202
+   10.. 14: ####################                                            727
+   15.. 19: ############                                                    452
+   20.. 24: ########                                                        284
+   25.. 29: ####                                                            164
+   30.. 34: ##                                                              103
+   35.. 39: #                                                                51
+   40.. 44:                                                                  26
+   45.. 49:                                                                  24
+   50.. 54:                                                                  15
+   55.. 59:                                                                   7
+   60.. 64:                                                                   3
+   65.. 69:                                                                   2
+   70.. 74:                                                                   2
+   75.. 79:                                                                   1
+   80.. 84:                                                                   1
+   85.. 89:                                                                   2
+   90.. 94:                                                                   0
+   95.. 99:                                                                   0
+
++++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: -9.56, stddev: 9.91, median -7, min -89, max 0
+  -89..-85:                                                                   2
+  -84..-80:                                                                   1
+  -79..-75:                                                                   1
+  -74..-70:                                                                   2
+  -69..-65:                                                                   2
+  -64..-60:                                                                   3
+  -59..-55:                                                                   7
+  -54..-50:                                                                  15
+  -49..-45:                                                                  24
+  -44..-40:                                                                  26
+  -39..-35: #                                                                51
+  -34..-30: ##                                                              103
+  -29..-25: ####                                                            164
+  -24..-20: ########                                                        284
+  -19..-15: ############                                                    452
+  -14..-10: ####################                                            727
+   -9.. -5: ##################################                             1202
+   -4..  0: #######################################################        1934
+    1..  5:                                                                   0
+    6.. 10:                                                                   0
 ================================================================================
 1 warning(s)
-failure (64 tests failed, 3 tests errored, ran 141 tests)
+failure (64 tests failed, 3 tests errored, ran 143 tests)
 random seed: 153870556
 
 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/test/core/QCheck2_expect_test.expected.ocaml5.32 b/test/core/QCheck2_expect_test.expected.ocaml5.32
index 4526d5f..b560f54 100644
--- a/test/core/QCheck2_expect_test.expected.ocaml5.32
+++ b/test/core/QCheck2_expect_test.expected.ocaml5.32
@@ -1395,9 +1395,59 @@ stats dist:
     751619287..  858993469:                                                                   0
     858993470..  966367652:                                                                   0
     966367653.. 1073741823: #################                                               195
+
++++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: 9.45, stddev: 9.82, median 6, min 0, max 79
+   0.. 3: #######################################################        1631
+   4.. 7: #####################################                          1109
+   8..11: #########################                                       747
+  12..15: #################                                               512
+  16..19: ##########                                                      308
+  20..23: ########                                                        251
+  24..27: #####                                                           165
+  28..31: ##                                                               85
+  32..35: ##                                                               64
+  36..39: #                                                                43
+  40..43:                                                                  25
+  44..47:                                                                  20
+  48..51:                                                                  20
+  52..55:                                                                   3
+  56..59:                                                                   8
+  60..63:                                                                   3
+  64..67:                                                                   1
+  68..71:                                                                   2
+  72..75:                                                                   2
+  76..79:                                                                   1
+
++++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: -9.45, stddev: 9.82, median -6, min -79, max 0
+  -79..-76:                                                                   1
+  -75..-72:                                                                   2
+  -71..-68:                                                                   2
+  -67..-64:                                                                   1
+  -63..-60:                                                                   3
+  -59..-56:                                                                   8
+  -55..-52:                                                                   3
+  -51..-48:                                                                  20
+  -47..-44:                                                                  20
+  -43..-40:                                                                  25
+  -39..-36: #                                                                43
+  -35..-32: ##                                                               64
+  -31..-28: ##                                                               85
+  -27..-24: #####                                                           165
+  -23..-20: ########                                                        251
+  -19..-16: ##########                                                      308
+  -15..-12: #################                                               512
+  -11.. -8: #########################                                       747
+   -7.. -4: #####################################                          1109
+   -3..  0: #######################################################        1631
 ================================================================================
 1 warning(s)
-failure (64 tests failed, 3 tests errored, ran 141 tests)
+failure (64 tests failed, 3 tests errored, ran 143 tests)
 random seed: 153870556
 
 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/test/core/QCheck2_expect_test.expected.ocaml5.64 b/test/core/QCheck2_expect_test.expected.ocaml5.64
index bce5b4b..7b24307 100644
--- a/test/core/QCheck2_expect_test.expected.ocaml5.64
+++ b/test/core/QCheck2_expect_test.expected.ocaml5.64
@@ -1451,9 +1451,59 @@ stats dist:
    3228180212899171968.. 3689348814741910783:                                                                   0
    3689348814741910784.. 4150517416584649599:                                                                   0
    4150517416584649600.. 4611686018427387903: #################                                               195
+
++++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: 9.45, stddev: 9.82, median 6, min 0, max 79
+   0.. 3: #######################################################        1631
+   4.. 7: #####################################                          1109
+   8..11: #########################                                       747
+  12..15: #################                                               512
+  16..19: ##########                                                      308
+  20..23: ########                                                        251
+  24..27: #####                                                           165
+  28..31: ##                                                               85
+  32..35: ##                                                               64
+  36..39: #                                                                43
+  40..43:                                                                  25
+  44..47:                                                                  20
+  48..51:                                                                  20
+  52..55:                                                                   3
+  56..59:                                                                   8
+  60..63:                                                                   3
+  64..67:                                                                   1
+  68..71:                                                                   2
+  72..75:                                                                   2
+  76..79:                                                                   1
+
++++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: -9.45, stddev: 9.82, median -6, min -79, max 0
+  -79..-76:                                                                   1
+  -75..-72:                                                                   2
+  -71..-68:                                                                   2
+  -67..-64:                                                                   1
+  -63..-60:                                                                   3
+  -59..-56:                                                                   8
+  -55..-52:                                                                   3
+  -51..-48:                                                                  20
+  -47..-44:                                                                  20
+  -43..-40:                                                                  25
+  -39..-36: #                                                                43
+  -35..-32: ##                                                               64
+  -31..-28: ##                                                               85
+  -27..-24: #####                                                           165
+  -23..-20: ########                                                        251
+  -19..-16: ##########                                                      308
+  -15..-12: #################                                               512
+  -11.. -8: #########################                                       747
+   -7.. -4: #####################################                          1109
+   -3..  0: #######################################################        1631
 ================================================================================
 1 warning(s)
-failure (64 tests failed, 3 tests errored, ran 141 tests)
+failure (64 tests failed, 3 tests errored, ran 143 tests)
 random seed: 153870556
 
 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/test/core/QCheck2_tests.ml b/test/core/QCheck2_tests.ml
index 1da328a..3f2add0 100644
--- a/test/core/QCheck2_tests.ml
+++ b/test/core/QCheck2_tests.ml
@@ -883,6 +883,12 @@ module Stats = struct
       Test.make ~name:"oneof int dist"                 ~count:1000   ~stats:[dist] (Gen.oneofl[min_int;-1;0;1;max_int]) (fun _ -> true);
     ]
 
+  let exponential_tests =
+    let float_dist = ("dist",int_of_float) in
+    [ Test.make ~name:"exponential 10. dist" ~count:5_000 ~stats:[float_dist] (Gen.exponential 10.) (fun _ -> true);
+      Test.make ~name:"exponential -10. dist" ~count:5_000 ~stats:[float_dist] (Gen.exponential (-10.)) (fun _ -> true);
+    ]
+
   let tree_depth_test =
     let depth = ("depth", IntTree.depth) in
     Test.make ~name:"tree's depth" ~count:1000 ~stats:[depth] IntTree.gen_tree (fun _ -> true)
@@ -904,4 +910,5 @@ module Stats = struct
     @ list_len_tests
     @ array_len_tests
     @ int_dist_tests
+    @ exponential_tests
 end
diff --git a/test/core/QCheck_expect_test.expected.ocaml4.32 b/test/core/QCheck_expect_test.expected.ocaml4.32
index bdbd94c..7aa93ab 100644
--- a/test/core/QCheck_expect_test.expected.ocaml4.32
+++ b/test/core/QCheck_expect_test.expected.ocaml4.32
@@ -1365,9 +1365,59 @@ stats dist:
     751619287..  858993469:                                                                   0
     858993470..  966367652:                                                                   0
     966367653.. 1073741823: #################                                               189
+
++++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: 9.56, stddev: 9.91, median 7, min 0, max 89
+    0..  4: #######################################################        1934
+    5..  9: ##################################                             1202
+   10.. 14: ####################                                            727
+   15.. 19: ############                                                    452
+   20.. 24: ########                                                        284
+   25.. 29: ####                                                            164
+   30.. 34: ##                                                              103
+   35.. 39: #                                                                51
+   40.. 44:                                                                  26
+   45.. 49:                                                                  24
+   50.. 54:                                                                  15
+   55.. 59:                                                                   7
+   60.. 64:                                                                   3
+   65.. 69:                                                                   2
+   70.. 74:                                                                   2
+   75.. 79:                                                                   1
+   80.. 84:                                                                   1
+   85.. 89:                                                                   2
+   90.. 94:                                                                   0
+   95.. 99:                                                                   0
+
++++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: -9.56, stddev: 9.91, median -7, min -89, max 0
+  -89..-85:                                                                   2
+  -84..-80:                                                                   1
+  -79..-75:                                                                   1
+  -74..-70:                                                                   2
+  -69..-65:                                                                   2
+  -64..-60:                                                                   3
+  -59..-55:                                                                   7
+  -54..-50:                                                                  15
+  -49..-45:                                                                  24
+  -44..-40:                                                                  26
+  -39..-35: #                                                                51
+  -34..-30: ##                                                              103
+  -29..-25: ####                                                            164
+  -24..-20: ########                                                        284
+  -19..-15: ############                                                    452
+  -14..-10: ####################                                            727
+   -9.. -5: ##################################                             1202
+   -4..  0: #######################################################        1934
+    1..  5:                                                                   0
+    6.. 10:                                                                   0
 ================================================================================
 1 warning(s)
-failure (64 tests failed, 3 tests errored, ran 149 tests)
+failure (64 tests failed, 3 tests errored, ran 151 tests)
 random seed: 153870556
 
 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/test/core/QCheck_expect_test.expected.ocaml4.64 b/test/core/QCheck_expect_test.expected.ocaml4.64
index 001496d..3cd4711 100644
--- a/test/core/QCheck_expect_test.expected.ocaml4.64
+++ b/test/core/QCheck_expect_test.expected.ocaml4.64
@@ -1397,9 +1397,59 @@ stats dist:
    3228180212899171968.. 3689348814741910783:                                                                   0
    3689348814741910784.. 4150517416584649599:                                                                   0
    4150517416584649600.. 4611686018427387903: #################                                               189
+
++++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: 9.56, stddev: 9.91, median 7, min 0, max 89
+    0..  4: #######################################################        1934
+    5..  9: ##################################                             1202
+   10.. 14: ####################                                            727
+   15.. 19: ############                                                    452
+   20.. 24: ########                                                        284
+   25.. 29: ####                                                            164
+   30.. 34: ##                                                              103
+   35.. 39: #                                                                51
+   40.. 44:                                                                  26
+   45.. 49:                                                                  24
+   50.. 54:                                                                  15
+   55.. 59:                                                                   7
+   60.. 64:                                                                   3
+   65.. 69:                                                                   2
+   70.. 74:                                                                   2
+   75.. 79:                                                                   1
+   80.. 84:                                                                   1
+   85.. 89:                                                                   2
+   90.. 94:                                                                   0
+   95.. 99:                                                                   0
+
++++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: -9.56, stddev: 9.91, median -7, min -89, max 0
+  -89..-85:                                                                   2
+  -84..-80:                                                                   1
+  -79..-75:                                                                   1
+  -74..-70:                                                                   2
+  -69..-65:                                                                   2
+  -64..-60:                                                                   3
+  -59..-55:                                                                   7
+  -54..-50:                                                                  15
+  -49..-45:                                                                  24
+  -44..-40:                                                                  26
+  -39..-35: #                                                                51
+  -34..-30: ##                                                              103
+  -29..-25: ####                                                            164
+  -24..-20: ########                                                        284
+  -19..-15: ############                                                    452
+  -14..-10: ####################                                            727
+   -9.. -5: ##################################                             1202
+   -4..  0: #######################################################        1934
+    1..  5:                                                                   0
+    6.. 10:                                                                   0
 ================================================================================
 1 warning(s)
-failure (64 tests failed, 3 tests errored, ran 149 tests)
+failure (64 tests failed, 3 tests errored, ran 151 tests)
 random seed: 153870556
 
 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/test/core/QCheck_expect_test.expected.ocaml5.32 b/test/core/QCheck_expect_test.expected.ocaml5.32
index 0c273ef..915f39c 100644
--- a/test/core/QCheck_expect_test.expected.ocaml5.32
+++ b/test/core/QCheck_expect_test.expected.ocaml5.32
@@ -1375,9 +1375,59 @@ stats dist:
     751619287..  858993469:                                                                   0
     858993470..  966367652:                                                                   0
     966367653.. 1073741823: #################                                               195
+
++++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: 9.45, stddev: 9.82, median 6, min 0, max 79
+   0.. 3: #######################################################        1631
+   4.. 7: #####################################                          1109
+   8..11: #########################                                       747
+  12..15: #################                                               512
+  16..19: ##########                                                      308
+  20..23: ########                                                        251
+  24..27: #####                                                           165
+  28..31: ##                                                               85
+  32..35: ##                                                               64
+  36..39: #                                                                43
+  40..43:                                                                  25
+  44..47:                                                                  20
+  48..51:                                                                  20
+  52..55:                                                                   3
+  56..59:                                                                   8
+  60..63:                                                                   3
+  64..67:                                                                   1
+  68..71:                                                                   2
+  72..75:                                                                   2
+  76..79:                                                                   1
+
++++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: -9.45, stddev: 9.82, median -6, min -79, max 0
+  -79..-76:                                                                   1
+  -75..-72:                                                                   2
+  -71..-68:                                                                   2
+  -67..-64:                                                                   1
+  -63..-60:                                                                   3
+  -59..-56:                                                                   8
+  -55..-52:                                                                   3
+  -51..-48:                                                                  20
+  -47..-44:                                                                  20
+  -43..-40:                                                                  25
+  -39..-36: #                                                                43
+  -35..-32: ##                                                               64
+  -31..-28: ##                                                               85
+  -27..-24: #####                                                           165
+  -23..-20: ########                                                        251
+  -19..-16: ##########                                                      308
+  -15..-12: #################                                               512
+  -11.. -8: #########################                                       747
+   -7.. -4: #####################################                          1109
+   -3..  0: #######################################################        1631
 ================================================================================
 1 warning(s)
-failure (64 tests failed, 3 tests errored, ran 149 tests)
+failure (64 tests failed, 3 tests errored, ran 151 tests)
 random seed: 153870556
 
 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/test/core/QCheck_expect_test.expected.ocaml5.64 b/test/core/QCheck_expect_test.expected.ocaml5.64
index 8105c9e..9c26971 100644
--- a/test/core/QCheck_expect_test.expected.ocaml5.64
+++ b/test/core/QCheck_expect_test.expected.ocaml5.64
@@ -1407,9 +1407,59 @@ stats dist:
    3228180212899171968.. 3689348814741910783:                                                                   0
    3689348814741910784.. 4150517416584649599:                                                                   0
    4150517416584649600.. 4611686018427387903: #################                                               195
+
++++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: 9.45, stddev: 9.82, median 6, min 0, max 79
+   0.. 3: #######################################################        1631
+   4.. 7: #####################################                          1109
+   8..11: #########################                                       747
+  12..15: #################                                               512
+  16..19: ##########                                                      308
+  20..23: ########                                                        251
+  24..27: #####                                                           165
+  28..31: ##                                                               85
+  32..35: ##                                                               64
+  36..39: #                                                                43
+  40..43:                                                                  25
+  44..47:                                                                  20
+  48..51:                                                                  20
+  52..55:                                                                   3
+  56..59:                                                                   8
+  60..63:                                                                   3
+  64..67:                                                                   1
+  68..71:                                                                   2
+  72..75:                                                                   2
+  76..79:                                                                   1
+
++++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+stats dist:
+  num: 5000, avg: -9.45, stddev: 9.82, median -6, min -79, max 0
+  -79..-76:                                                                   1
+  -75..-72:                                                                   2
+  -71..-68:                                                                   2
+  -67..-64:                                                                   1
+  -63..-60:                                                                   3
+  -59..-56:                                                                   8
+  -55..-52:                                                                   3
+  -51..-48:                                                                  20
+  -47..-44:                                                                  20
+  -43..-40:                                                                  25
+  -39..-36: #                                                                43
+  -35..-32: ##                                                               64
+  -31..-28: ##                                                               85
+  -27..-24: #####                                                           165
+  -23..-20: ########                                                        251
+  -19..-16: ##########                                                      308
+  -15..-12: #################                                               512
+  -11.. -8: #########################                                       747
+   -7.. -4: #####################################                          1109
+   -3..  0: #######################################################        1631
 ================================================================================
 1 warning(s)
-failure (64 tests failed, 3 tests errored, ran 149 tests)
+failure (64 tests failed, 3 tests errored, ran 151 tests)
 random seed: 153870556
 
 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/test/core/QCheck_tests.ml b/test/core/QCheck_tests.ml
index 1d1779a..dd5b7ec 100644
--- a/test/core/QCheck_tests.ml
+++ b/test/core/QCheck_tests.ml
@@ -955,6 +955,12 @@ module Stats = struct
       Test.make ~name:"oneof int dist"                 ~count:1000   (add_stat dist (oneofl[min_int;-1;0;1;max_int])) (fun _ -> true);
     ]
 
+  let exponential_tests =
+    let float_dist = ("dist",int_of_float) in
+    [ Test.make ~name:"exponential 10. dist" ~count:5_000 (add_stat float_dist (exponential 10.)) (fun _ -> true);
+      Test.make ~name:"exponential -10. dist" ~count:5_000 (add_stat float_dist (exponential (-10.))) (fun _ -> true);
+    ]
+
   let tree_depth_test =
     let depth = ("depth", IntTree.depth) in
     Test.make ~name:"tree's depth" ~count:1000 (add_stat depth (make IntTree.gen_tree)) (fun _ -> true)
@@ -982,4 +988,5 @@ module Stats = struct
     @ list_len_tests
     @ array_len_tests
     @ int_dist_tests
+    @ exponential_tests
 end