summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.xml23
-rw-r--r--src/build/maven/scala-library-pom.xml29
-rw-r--r--src/library/scala/collection/mutable/HashTable.scala2
-rw-r--r--src/library/scala/concurrent/ConcurrentPackageObject.scala30
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala6
-rw-r--r--src/library/scala/concurrent/Future.scala33
-rw-r--r--src/library/scala/concurrent/impl/ExecutionContextImpl.scala42
-rw-r--r--src/library/scala/concurrent/impl/Future.scala30
-rw-r--r--src/library/scala/concurrent/impl/Promise.scala2
-rw-r--r--src/library/scala/math/BigDecimal.scala15
-rw-r--r--src/library/scala/math/BigInt.scala38
-rw-r--r--test/files/run/is-valid-num.scala77
-rw-r--r--test/files/run/numbereq.scala35
13 files changed, 288 insertions, 74 deletions
diff --git a/build.xml b/build.xml
index 56c9bccf57..c1ab09c4e4 100644
--- a/build.xml
+++ b/build.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project name="sabbus" default="build">
+<project name="sabbus" default="build" xmlns:artifact="urn:maven-artifact-ant">
<description>
SuperSabbus for Scala core, builds the scala library and compiler. It can also package it as a simple distribution, tests it for stable bootstrapping and against the Scala test suite.
</description>
@@ -238,6 +238,19 @@ INITIALISATION
</touch>
</target>
+ <!-- Add our maven ant tasks -->
+ <target name="init.maven.tasks" depends="init.jars.check">
+ <path id="maven-ant-tasks.classpath" path="${lib.dir}/ant/maven-ant-tasks-2.1.1.jar" />
+ <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
+ </target>
+
+ <!-- Resolve maven dependencies -->
+ <target name="init.maven.jars" depends="init.maven.tasks">
+ <artifact:dependencies pathId="dependency.classpath" filesetId="dependency.fileset">
+ <dependency groupId="org.skife.com.typesafe.config" artifactId="typesafe-config" version="0.3.0"/>
+ </artifact:dependencies>
+ </target>
+
<!-- Determines OSGi string + maven extension. -->
<target name="init.hasbuildnum">
<condition property="version.hasbuildnum">
@@ -296,7 +309,7 @@ INITIALISATION
<target name="init.version.done" depends="init.version.release, init.version.snapshot"/>
- <target name="init" depends="init.jars, init.version.done">
+ <target name="init" depends="init.jars, init.maven.jars, init.version.done">
<!-- scalac.args.optimise is selectively overridden in certain antcall tasks. -->
<property name="scalac.args.optimise" value=""/>
<!-- scalac.args.quickonly are added to quick.* targets but not others (particularly, locker.)
@@ -337,6 +350,7 @@ INITIALISATION
</fileset>
<pathelement location="${ant.jar}"/>
<path refid="lib.extra"/>
+ <path refid="dependency.classpath"/>
</path>
<!-- And print-out what we are building -->
@@ -1002,6 +1016,11 @@ PACKED QUICK BUILD (PACK)
<target name="pack.lib" depends="pack.pre-lib" unless="pack.lib.available">
<mkdir dir="${build-pack.dir}/lib"/>
+ <!-- First copy maven dependencies -->
+ <copy todir="${build-pack.dir}/lib">
+ <fileset refid="dependency.fileset" />
+ <mapper type="flatten" />
+ </copy>
<jar destfile="${build-pack.dir}/lib/scala-library.jar">
<fileset dir="${build-quick.dir}/classes/library">
<exclude name="scala/dbc/**"/>
diff --git a/src/build/maven/scala-library-pom.xml b/src/build/maven/scala-library-pom.xml
index 673c3dfada..c3f8a4531c 100644
--- a/src/build/maven/scala-library-pom.xml
+++ b/src/build/maven/scala-library-pom.xml
@@ -30,17 +30,24 @@
<system>JIRA</system>
<url>https://issues.scala-lang.org/</url>
</issueManagement>
- <distributionManagement>
- <repository>
- <id>scala-tools.org</id>
- <url>@RELEASE_REPOSITORY@</url>
- </repository>
- <snapshotRepository>
- <id>scala-tools.org</id>
- <url>@SNAPSHOT_REPOSITORY@</url>
- <uniqueVersion>false</uniqueVersion>
- </snapshotRepository>
- </distributionManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.skife.com.typesafe.config</groupId>
+ <artifactId>typesafe-config</artifactId>
+ <version>0.3.0</version>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <repository>
+ <id>scala-tools.org</id>
+ <url>@RELEASE_REPOSITORY@</url>
+ </repository>
+ <snapshotRepository>
+ <id>scala-tools.org</id>
+ <url>@SNAPSHOT_REPOSITORY@</url>
+ <uniqueVersion>false</uniqueVersion>
+ </snapshotRepository>
+ </distributionManagement>
<developers>
<developer>
<id>lamp</id>
diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala
index cc0aed6963..06b7d40bfc 100644
--- a/src/library/scala/collection/mutable/HashTable.scala
+++ b/src/library/scala/collection/mutable/HashTable.scala
@@ -366,7 +366,7 @@ private[collection] object HashTable {
private[collection] final def newThreshold(_loadFactor: Int, size: Int) = ((size.toLong * _loadFactor) / loadFactorDenum).toInt
- private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = thr * loadFactorDenum / _loadFactor
+ private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = ((thr.toLong * loadFactorDenum) / _loadFactor).toInt
private[collection] final def capacity(expectedSize: Int) = if (expectedSize == 0) 1 else powerOfTwo(expectedSize)
diff --git a/src/library/scala/concurrent/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala
index ba98757906..f4744a8757 100644
--- a/src/library/scala/concurrent/ConcurrentPackageObject.scala
+++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala
@@ -10,8 +10,8 @@ package scala.concurrent
-import java.util.concurrent.{ Executors, ExecutorService }
-import scala.concurrent.forkjoin.ForkJoinPool
+import java.util.concurrent.{ Executors, ExecutorService, ThreadFactory }
+import scala.concurrent.forkjoin.{ ForkJoinPool, ForkJoinWorkerThread }
import scala.util.{ Try, Success, Failure }
import scala.concurrent.util.Duration
import ConcurrentPackageObject._
@@ -24,14 +24,9 @@ abstract class ConcurrentPackageObject {
/** A global execution environment for executing lightweight tasks.
*/
lazy val executionContext =
- new impl.ExecutionContextImpl(getExecutorService)
-
- private[concurrent] def getExecutorService: AnyRef =
- if (scala.util.Properties.isJavaAtLeast("1.6")) {
- val vendor = scala.util.Properties.javaVmVendor
- if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple")) new ForkJoinPool
- else Executors.newCachedThreadPool()
- } else Executors.newCachedThreadPool()
+ new impl.ExecutionContextImpl()
+
+ private val currentExecutionContext = new ThreadLocal[ExecutionContext]
val handledFutureException: PartialFunction[Throwable, Throwable] = {
case t: Throwable if isFutureThrowable(t) => t
@@ -58,10 +53,10 @@ abstract class ConcurrentPackageObject {
/* concurrency constructs */
- def future[T](body: =>T)(implicit execCtx: ExecutionContext = executionContext): Future[T] =
+ def future[T](body: =>T)(implicit execctx: ExecutionContext = executionContext): Future[T] =
Future[T](body)
- def promise[T]()(implicit execCtx: ExecutionContext = executionContext): Promise[T] =
+ def promise[T]()(implicit execctx: ExecutionContext = executionContext): Promise[T] =
Promise[T]()
/** Wraps a block of code into an awaitable object. */
@@ -82,8 +77,8 @@ abstract class ConcurrentPackageObject {
* - InterruptedException - in the case that a wait within the blockable object was interrupted
* - TimeoutException - in the case that the blockable object timed out
*/
- def blocking[T](body: =>T)(implicit execCtx: ExecutionContext): T =
- executionContext.blocking(body)
+ def blocking[T](body: =>T): T =
+ blocking(body2awaitable(body), Duration.fromNanos(0))
/** Blocks on an awaitable object.
*
@@ -94,8 +89,11 @@ abstract class ConcurrentPackageObject {
* - InterruptedException - in the case that a wait within the blockable object was interrupted
* - TimeoutException - in the case that the blockable object timed out
*/
- def blocking[T](awaitable: Awaitable[T], atMost: Duration)(implicit execCtx: ExecutionContext = executionContext): T =
- executionContext.blocking(awaitable, atMost)
+ def blocking[T](awaitable: Awaitable[T], atMost: Duration): T =
+ currentExecutionContext.get match {
+ case null => Await.result(awaitable, atMost)
+ case ec => ec.internalBlockingCall(awaitable, atMost)
+ }
@inline implicit final def int2durationops(x: Int): DurationOps = new DurationOps(x)
}
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index a206a2d4ea..f639f76dc9 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -26,10 +26,8 @@ trait ExecutionContext {
def execute[U](body: () => U): Unit
- def blocking[T](body: =>T): T
-
- def blocking[T](awaitable: Awaitable[T], atMost: Duration): T
-
+ def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T
+
def reportFailure(t: Throwable): Unit
/* implementations follow */
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index d73801aa90..8cecadc605 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -274,6 +274,18 @@ self =>
p.future
}
+ /** Used by for-comprehensions.
+ */
+ final def withFilter(p: T => Boolean): Future[T] = filter(p)
+ // final def withFilter(p: T => Boolean) = new FutureWithFilter[T](this, p)
+
+ // final class FutureWithFilter[+S](self: Future[S], p: S => Boolean) {
+ // def foreach(f: S => Unit): Unit = self filter p foreach f
+ // def map[R](f: S => R) = self filter p map f
+ // def flatMap[R](f: S => Future[R]) = self filter p flatMap f
+ // def withFilter(q: S => Boolean): FutureWithFilter[S] = new FutureWithFilter[S](self, x => p(x) && q(x))
+ // }
+
/** Creates a new future by mapping the value of the current future if the given partial function is defined at that value.
*
* If the current future contains a value for which the partial function is defined, the new future will also hold that value.
@@ -417,7 +429,26 @@ self =>
p.future
}
-
+
+ /** Creates a new `Future[S]` which is completed with this `Future`'s result if
+ * that conforms to `S`'s erased type or a `ClassCastException` otherwise.
+ */
+ def mapTo[S](implicit m: Manifest[S]): Future[S] = {
+ val p = newPromise[S]
+
+ onComplete {
+ case l: Failure[_] => p complete l.asInstanceOf[Try[S]]
+ case Success(t) =>
+ p complete (try {
+ Success(impl.Future.boxedType(m.erasure).cast(t).asInstanceOf[S])
+ } catch {
+ case e: ClassCastException => Failure(e)
+ })
+ }
+
+ p.future
+ }
+
/** Applies the side-effecting function to the result of this future, and returns
* a new future with the result of this future.
*
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
index 5dc440f42b..2cfd6f22cd 100644
--- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
@@ -10,7 +10,7 @@ package scala.concurrent.impl
-import java.util.concurrent.{Callable, ExecutorService}
+import java.util.concurrent.{Callable, ExecutorService, Executors, ThreadFactory}
import scala.concurrent.forkjoin._
import scala.concurrent.{ExecutionContext, resolver, Awaitable, body2awaitable}
import scala.util.{ Try, Success, Failure }
@@ -18,8 +18,42 @@ import scala.concurrent.util.{ Duration }
-private[scala] class ExecutionContextImpl(val executorService: AnyRef) extends ExecutionContext {
+private[scala] class ExecutionContextImpl() extends ExecutionContext {
import ExecutionContextImpl._
+
+ val executorService: AnyRef = getExecutorService
+
+ // to ensure that the current execution context thread local is properly set
+ private def executorsThreadFactory = new ThreadFactory {
+ def newThread(r: Runnable) = new Thread(new Runnable {
+ override def run() {
+ currentExecutionContext.set(ExecutionContextImpl.this)
+ r.run()
+ }
+ })
+ }
+
+ // to ensure that the current execution context thread local is properly set
+ private def forkJoinPoolThreadFactory = new ForkJoinPool.ForkJoinWorkerThreadFactory {
+ def newThread(fjp: ForkJoinPool) = new ForkJoinWorkerThread(fjp) {
+ override def onStart() {
+ currentExecutionContext.set(ExecutionContextImpl.this)
+ }
+ }
+ }
+
+ private def getExecutorService: AnyRef =
+ if (scala.util.Properties.isJavaAtLeast("1.6")) {
+ val vendor = scala.util.Properties.javaVmVendor
+ if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple"))
+ new ForkJoinPool(
+ Runtime.getRuntime.availableProcessors(),
+ forkJoinPoolThreadFactory,
+ null,
+ false)
+ else
+ Executors.newCachedThreadPool(executorsThreadFactory)
+ } else Executors.newCachedThreadPool(executorsThreadFactory)
def execute(runnable: Runnable): Unit = executorService match {
case fj: ForkJoinPool =>
@@ -37,9 +71,7 @@ private[scala] class ExecutionContextImpl(val executorService: AnyRef) extends E
def run() = body()
})
- def blocking[T](body: =>T): T = blocking(body2awaitable(body), Duration.fromNanos(0))
-
- def blocking[T](awaitable: Awaitable[T], atMost: Duration): T = {
+ def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T = {
Future.releaseStack(this)
awaitable.result(atMost)(scala.concurrent.Await.canAwaitEvidence)
diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala
index 6833b2467f..1111aa4753 100644
--- a/src/library/scala/concurrent/impl/Future.scala
+++ b/src/library/scala/concurrent/impl/Future.scala
@@ -40,36 +40,6 @@ private[concurrent] trait Future[+T] extends scala.concurrent.Future[T] with Awa
def onComplete[U](func: Try[T] => U): this.type
- /** Creates a new Future[A] which is completed with this Future's result if
- * that conforms to A's erased type or a ClassCastException otherwise.
- */
- final def mapTo[T](implicit m: Manifest[T]) = {
- val p = new Promise.DefaultPromise[T]
-
- onComplete {
- case f @ Failure(t) => p complete f.asInstanceOf[Try[T]]
- case Success(v) =>
- p complete (try {
- Success(Future.boxedType(m.erasure).cast(v).asInstanceOf[T])
- } catch {
- case e: ClassCastException => Failure(e)
- })
- }
-
- p.future
- }
-
- /** Used by for-comprehensions.
- */
- final def withFilter(p: T => Boolean) = new FutureWithFilter[T](this, p)
-
- final class FutureWithFilter[+A](self: Future[A], p: A => Boolean) {
- def foreach(f: A => Unit): Unit = self filter p foreach f
- def map[B](f: A => B) = self filter p map f
- def flatMap[B](f: A => Future[B]) = self filter p flatMap f
- def withFilter(q: A => Boolean): FutureWithFilter[A] = new FutureWithFilter[A](self, x ⇒ p(x) && q(x))
- }
-
}
object Future {
diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala
index c79b0d02cc..f05e306088 100644
--- a/src/library/scala/concurrent/impl/Promise.scala
+++ b/src/library/scala/concurrent/impl/Promise.scala
@@ -127,7 +127,7 @@ object Promise {
value.isDefined
}
- executor.blocking(concurrent.body2awaitable(awaitUnsafe(dur2long(atMost))), atMost)
+ blocking(concurrent.body2awaitable(awaitUnsafe(dur2long(atMost))), atMost)
}
def ready(atMost: Duration)(implicit permit: CanAwait): this.type =
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index c1f45eccfb..cb42b76b51 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -183,7 +183,8 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
override def equals (that: Any): Boolean = that match {
case that: BigDecimal => this equals that
case that: BigInt => this.toBigIntExact exists (that equals _)
- case _: Float | _: Double => unifiedPrimitiveEquals(that)
+ case that: Double => isValidDouble && toDouble == that
+ case that: Float => isValidFloat && toFloat == that
case _ => isValidLong && unifiedPrimitiveEquals(that)
}
override def isValidByte = noArithmeticException(toByteExact)
@@ -191,6 +192,18 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
override def isValidChar = isValidInt && toIntExact >= Char.MinValue && toIntExact <= Char.MaxValue
override def isValidInt = noArithmeticException(toIntExact)
def isValidLong = noArithmeticException(toLongExact)
+ /** Returns `true` iff this can be represented exactly by [[scala.Float]]; otherwise returns `false`.
+ */
+ def isValidFloat = {
+ val f = toFloat
+ !f.isInfinity && bigDecimal.compareTo(new java.math.BigDecimal(f)) == 0
+ }
+ /** Returns `true` iff this can be represented exactly by [[scala.Double]]; otherwise returns `false`.
+ */
+ def isValidDouble = {
+ val d = toDouble
+ !d.isInfinity && bigDecimal.compareTo(new java.math.BigDecimal(d)) == 0
+ }
private def noArithmeticException(body: => Unit): Boolean = {
try { body ; true }
diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala
index 8a53afaa62..dbec30b2fe 100644
--- a/src/library/scala/math/BigInt.scala
+++ b/src/library/scala/math/BigInt.scala
@@ -20,6 +20,7 @@ object BigInt {
private val minCached = -1024
private val maxCached = 1024
private val cache = new Array[BigInt](maxCached - minCached + 1)
+ private val minusOne = BigInteger.valueOf(-1)
@deprecated("Use Long.MinValue", "2.9.0")
val MinLong = BigInt(Long.MinValue)
@@ -122,6 +123,8 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo
override def equals(that: Any): Boolean = that match {
case that: BigInt => this equals that
case that: BigDecimal => that.toBigIntExact exists (this equals _)
+ case that: Double => isValidDouble && toDouble == that
+ case that: Float => isValidFloat && toFloat == that
case x => isValidLong && unifiedPrimitiveEquals(x)
}
override def isValidByte = this >= Byte.MinValue && this <= Byte.MaxValue
@@ -129,6 +132,41 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo
override def isValidChar = this >= Char.MinValue && this <= Char.MaxValue
override def isValidInt = this >= Int.MinValue && this <= Int.MaxValue
def isValidLong = this >= Long.MinValue && this <= Long.MaxValue
+ /** Returns `true` iff this can be represented exactly by [[scala.Float]]; otherwise returns `false`.
+ */
+ def isValidFloat = {
+ val bitLen = bitLength
+ (bitLen <= 24 ||
+ {
+ val lowest = lowestSetBit
+ bitLen <= java.lang.Float.MAX_EXPONENT + 1 && // exclude this < -2^128 && this >= 2^128
+ lowest >= bitLen - 24 &&
+ lowest < java.lang.Float.MAX_EXPONENT + 1 // exclude this == -2^128
+ }
+ ) && !bitLengthOverflow
+ }
+ /** Returns `true` iff this can be represented exactly by [[scala.Double]]; otherwise returns `false`.
+ */
+ def isValidDouble = {
+ val bitLen = bitLength
+ (bitLen <= 53 ||
+ {
+ val lowest = lowestSetBit
+ bitLen <= java.lang.Double.MAX_EXPONENT + 1 && // exclude this < -2^1024 && this >= 2^1024
+ lowest >= bitLen - 53 &&
+ lowest < java.lang.Double.MAX_EXPONENT + 1 // exclude this == -2^1024
+ }
+ ) && !bitLengthOverflow
+ }
+ /** Some implementations of java.math.BigInteger allow huge values with bit length greater than Int.MaxValue .
+ * The BigInteger.bitLength method returns truncated bit length in this case .
+ * This method tests if result of bitLength is valid.
+ * This method will become unnecessary if BigInt constructors reject huge BigIntegers.
+ */
+ private def bitLengthOverflow = {
+ val shifted = bigInteger.shiftRight(Int.MaxValue)
+ (shifted.signum != 0) && !(shifted equals BigInt.minusOne)
+ }
protected[math] def isWhole = true
def underlying = bigInteger
diff --git a/test/files/run/is-valid-num.scala b/test/files/run/is-valid-num.scala
index f919a21dee..9c43e98911 100644
--- a/test/files/run/is-valid-num.scala
+++ b/test/files/run/is-valid-num.scala
@@ -1,11 +1,15 @@
object Test {
def x = BigInt("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
def y = BigDecimal("" + (Short.MaxValue + 1) + ".0")
+ def y1 = BigDecimal("0.1")
+ def y2 = BigDecimal("0.5")
def l1 = Int.MaxValue.toLong + 1
def l2 = Int.MinValue.toLong - 1
def main(args: Array[String]): Unit = {
+ assert(!x.isValidDouble, x)
+ assert(!x.isValidFloat, x)
assert(!x.isValidLong, x)
assert(!x.isValidInt, x)
assert(!x.isValidChar, x)
@@ -13,8 +17,81 @@ object Test {
assert(!y.isValidShort, y)
assert(y.isValidChar, y)
assert(y.isValidInt, y)
+ assert(y.isValidFloat, y)
+ assert(y.isValidDouble, y)
+ assert(!y1.isValidLong, y1)
+ assert(!y1.isValidFloat, y1)
+ assert(!y1.isValidDouble, y1)
+ assert(!y2.isValidLong, y2)
+ assert(y2.isValidFloat, y2)
+ assert(y2.isValidDouble, y2)
+
+ testBigIntIsFloat()
+ testBigIntIsDouble()
assert(!l1.isValidInt && (l1 - 1).isValidInt, l1)
assert(!l2.isValidInt && (l2 + 1).isValidInt, l2)
}
+
+ def biExp2(e: Int) = BigInt(1) << e
+
+ def testBigIntIsFloat() {
+ val prec = 24
+ def checkFloatT(x: BigInt) = {
+ assert(x.isValidFloat, x)
+ assert((-x).isValidFloat, -x)
+ }
+ def checkFloatF(x: BigInt) = {
+ assert(!x.isValidFloat, x)
+ assert(!(-x).isValidFloat, -x)
+ }
+ checkFloatT(biExp2(prec) - 1)
+ checkFloatT(biExp2(prec))
+ checkFloatF(biExp2(prec) + 1)
+ checkFloatT(biExp2(prec) + 2)
+ checkFloatT(biExp2(prec) - 2)
+ checkFloatF(biExp2(prec + 1) - 1)
+ checkFloatT(biExp2(prec + 1))
+ checkFloatF(biExp2(prec + 1) + 1)
+ checkFloatF(biExp2(prec + 1) + 2)
+ checkFloatF(biExp2(prec + 1) + 3)
+ checkFloatT(biExp2(prec + 1) + 4)
+ checkFloatT(biExp2(64))
+ checkFloatF(biExp2(64) + biExp2(64 - prec))
+ checkFloatT(biExp2(64) + biExp2(64 - prec + 1))
+ checkFloatT(biExp2(127))
+ checkFloatT(biExp2(128) - biExp2(128 - prec))
+ checkFloatF(biExp2(128) - biExp2(128 - prec - 1))
+ checkFloatF(biExp2(128))
+ }
+
+ def testBigIntIsDouble() {
+ val prec = 53
+ def checkDoubleT(x: BigInt) = {
+ assert(x.isValidDouble, x)
+ assert((-x).isValidDouble, -x)
+ }
+ def checkDoubleF(x: BigInt) = {
+ assert(!x.isValidDouble, x)
+ assert(!(-x).isValidDouble, -x)
+ }
+ checkDoubleT(biExp2(prec) - 1)
+ checkDoubleT(biExp2(prec))
+ checkDoubleF(biExp2(prec) + 1)
+ checkDoubleT(biExp2(prec) + 2)
+ checkDoubleT(biExp2(prec + 1) - 2)
+ checkDoubleF(biExp2(prec + 1) - 1)
+ checkDoubleT(biExp2(prec + 1))
+ checkDoubleF(biExp2(prec + 1) + 1)
+ checkDoubleF(biExp2(prec + 1) + 2)
+ checkDoubleF(biExp2(prec + 1) + 3)
+ checkDoubleT(biExp2(prec + 1) + 4)
+ checkDoubleT(biExp2(64))
+ checkDoubleF(biExp2(64) + biExp2(64 - prec))
+ checkDoubleT(biExp2(64) + biExp2(64 - prec + 1))
+ checkDoubleT(biExp2(1023))
+ checkDoubleT(biExp2(1024) - biExp2(1024 - prec))
+ checkDoubleF(biExp2(1024) - biExp2(1024 - prec - 1))
+ checkDoubleF(biExp2(1024))
+ }
}
diff --git a/test/files/run/numbereq.scala b/test/files/run/numbereq.scala
index 77a217df36..a1f11da205 100644
--- a/test/files/run/numbereq.scala
+++ b/test/files/run/numbereq.scala
@@ -16,7 +16,20 @@ object Test {
base ::: extras
}
-
+
+ def mkNumbers(x: BigInt): List[AnyRef] = {
+ List(
+ List(BigDecimal(x, java.math.MathContext.UNLIMITED)),
+ List(x),
+ if (x.isValidDouble) List(new java.lang.Double(x.toDouble)) else Nil,
+ if (x.isValidFloat) List(new java.lang.Float(x.toFloat)) else Nil,
+ if (x.isValidLong) List(new java.lang.Long(x.toLong)) else Nil,
+ if (x.isValidInt) List(new java.lang.Integer(x.toInt)) else Nil,
+ if (x.isValidShort) List(new java.lang.Short(x.toShort)) else Nil,
+ if (x.isValidByte) List(new java.lang.Byte(x.toByte)) else Nil,
+ if (x.isValidChar) List(new java.lang.Character(x.toChar)) else Nil
+ ).flatten
+ }
def main(args: Array[String]): Unit = {
val ints = (0 to 15).toList map (Short.MinValue >> _)
@@ -37,5 +50,23 @@ object Test {
assert(x == y, "%s/%s != %s/%s".format(x, x.getClass, y, y.getClass))
assert(x.## == y.##, "%s != %s".format(x.getClass, y.getClass))
}
+
+ val bigInts = (0 to 1024).toList map (BigInt(-1) << _)
+ val bigInts2 = bigInts map (x => -x)
+ val bigInts3 = bigInts map (_ + 1)
+ val bigInts4 = bigInts2 map (_ - 1)
+
+ val setneg1b = bigInts map mkNumbers
+ val setneg2b = bigInts3 map mkNumbers
+ val setpos1b = bigInts2 map mkNumbers
+ val setpos2b = bigInts4 map mkNumbers
+
+ val sets2 = setneg1 ++ setneg1b ++ setneg2 ++ setneg2b ++ List(zero) ++ setpos1 ++ setpos1b ++ setpos2 ++ setpos2b
+
+ for (set <- sets2 ; x <- set ; y <- set) {
+// println("'%s' == '%s' (%s == %s) (%s == %s)".format(x, y, x.hashCode, y.hashCode, x.##, y.##))
+ assert(x == y, "%s/%s != %s/%s".format(x, x.getClass, y, y.getClass))
+// assert(x.## == y.##, "%s != %s".format(x.getClass, y.getClass)) Disable until Double.## is fixed (SI-5640)
+ }
}
-} \ No newline at end of file
+}