From 5d5de562daa154aa0b4e87f037fb46a8eb5a1b09 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Tue, 6 Feb 2024 08:06:35 +0900 Subject: [PATCH] add Random.nextLong(Long) --- .../collection/compat/PackageShared.scala | 4 +++ .../collection/compat/RandomExtensions.scala | 36 +++++++++++++++++++ .../scala/test/scala/util/RandomTest.scala | 34 ++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 compat/src/main/scala-2.11_2.12/scala/collection/compat/RandomExtensions.scala create mode 100644 compat/src/test/scala/test/scala/util/RandomTest.scala diff --git a/compat/src/main/scala-2.11_2.12/scala/collection/compat/PackageShared.scala b/compat/src/main/scala-2.11_2.12/scala/collection/compat/PackageShared.scala index a0670d0a..5aa45f83 100644 --- a/compat/src/main/scala-2.11_2.12/scala/collection/compat/PackageShared.scala +++ b/compat/src/main/scala-2.11_2.12/scala/collection/compat/PackageShared.scala @@ -25,6 +25,7 @@ import scala.collection.{ mutable => m } import scala.runtime.{Tuple2Zipped, Tuple3Zipped} +import scala.util.Random import scala.{collection => c} /** The collection compatibility API */ @@ -351,6 +352,9 @@ private[compat] trait PackageShared { implicit def toOptionCompanionExtension(fact: Option.type): OptionCompanionExtensionMethods = new OptionCompanionExtensionMethods(fact) + + implicit def toRandomExtensions(self: Random): RandomExtensions = + new RandomExtensions(self) } class ImmutableSortedMapExtensions(private val fact: i.SortedMap.type) extends AnyVal { diff --git a/compat/src/main/scala-2.11_2.12/scala/collection/compat/RandomExtensions.scala b/compat/src/main/scala-2.11_2.12/scala/collection/compat/RandomExtensions.scala new file mode 100644 index 00000000..1cb82f21 --- /dev/null +++ b/compat/src/main/scala-2.11_2.12/scala/collection/compat/RandomExtensions.scala @@ -0,0 +1,36 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala.collection.compat + +import scala.util.Random + +final class RandomExtensions(private val self: Random) extends AnyVal { + def nextLong(n: Long): Long = { + require(n > 0, "n must be positive") + + var offset = 0L + var _n = n + + while (_n >= Integer.MAX_VALUE) { + val bits = self.nextInt(2) + val halfn = _n >>> 1 + val nextn = + if ((bits & 2) == 0) halfn + else _n - halfn + if ((bits & 1) == 0) + offset += _n - nextn + _n = nextn + } + offset + self.nextInt(_n.toInt) + } +} diff --git a/compat/src/test/scala/test/scala/util/RandomTest.scala b/compat/src/test/scala/test/scala/util/RandomTest.scala new file mode 100644 index 00000000..21468721 --- /dev/null +++ b/compat/src/test/scala/test/scala/util/RandomTest.scala @@ -0,0 +1,34 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package test.scala.util + +import org.junit.Assert._ +import org.junit.Test +import scala.collection.compat._ +import scala.util.Random +import test.scala.collection.AssertThrown + +class RandomTest extends AssertThrown { + @Test + def nextLong(): Unit = { + val rand = new Random(12345) + + assertEquals(4896762128577075113L, rand.nextLong(Long.MaxValue)) + assertEquals(2005076556L, rand.nextLong(Int.MaxValue)) + assertEquals(0L, rand.nextLong(1L)) + + assertThrows[IllegalArgumentException](rand.nextLong(0L)) + assertThrows[IllegalArgumentException](rand.nextLong(-2L)) + assertThrows[IllegalArgumentException](rand.nextLong(Long.MinValue)) + } +}