summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRex Kerr <ichoran@gmail.com>2014-02-24 16:45:56 -0800
committerRex Kerr <ichoran@gmail.com>2014-02-25 08:49:02 -0800
commit1994a2d901e1ca948a53b3d00df9017782c47b5c (patch)
tree42a2579146086534abc772d2c1420a2a7340e14d
parent1ea43ffb2286d63e133839c1ea0b09449b0ac168 (diff)
downloadscala-1994a2d901e1ca948a53b3d00df9017782c47b5c.tar.gz
scala-1994a2d901e1ca948a53b3d00df9017782c47b5c.tar.bz2
scala-1994a2d901e1ca948a53b3d00df9017782c47b5c.zip
SI-3235 math.round() returns wrong results for Int and Long
Minimal fix for SI-3235. This minimal fix includes deprecation messages to aid detection of probable errors. Test verifies behavior: the correct values are returned, and deprecation messages are emitted.
-rw-r--r--src/library/scala/math/package.scala16
-rw-r--r--src/library/scala/runtime/RichInt.scala4
-rw-r--r--src/library/scala/runtime/RichLong.scala4
-rw-r--r--test/files/run/t3235-minimal.check12
-rw-r--r--test/files/run/t3235-minimal.flags1
-rw-r--r--test/files/run/t3235-minimal.scala8
6 files changed, 42 insertions, 3 deletions
diff --git a/src/library/scala/math/package.scala b/src/library/scala/math/package.scala
index af5dad5c38..58ece8a05b 100644
--- a/src/library/scala/math/package.scala
+++ b/src/library/scala/math/package.scala
@@ -93,12 +93,22 @@ package object math {
*/
def pow(x: Double, y: Double): Double = java.lang.Math.pow(x, y)
- /** Returns the closest `long` to the argument.
+ /** There is no reason to round a `Long`, but this method prevents unintended conversion to `Float` followed by rounding to `Int`. */
+ @deprecated("This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value?", "2.11.0")
+ def round(x: Long): Long = x
+
+ /** Returns the closest `Int` to the argument.
*
- * @param x a floating-point value to be rounded to a `long`.
- * @return the value of the argument rounded to the nearest`long` value.
+ * @param x a floating-point value to be rounded to a `Int`.
+ * @return the value of the argument rounded to the nearest `Int` value.
*/
def round(x: Float): Int = java.lang.Math.round(x)
+
+ /** Returns the closest `Long` to the argument.
+ *
+ * @param x a floating-point value to be rounded to a `Long`.
+ * @return the value of the argument rounded to the nearest`long` value.
+ */
def round(x: Double): Long = java.lang.Math.round(x)
def abs(x: Int): Int = java.lang.Math.abs(x)
diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala
index cc4e92dfa3..cda9d2907a 100644
--- a/src/library/scala/runtime/RichInt.scala
+++ b/src/library/scala/runtime/RichInt.scala
@@ -36,6 +36,10 @@ final class RichInt(val self: Int) extends AnyVal with ScalaNumberProxy[Int] wit
override def max(that: Int): Int = math.max(self, that)
override def min(that: Int): Int = math.min(self, that)
override def signum: Int = math.signum(self)
+
+ /** There is no reason to round an `Int`, but this method is provided to avoid accidental loss of precision from a detour through `Float`. */
+ @deprecated("This is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value?", "2.11.0")
+ def round: Int = self
def toBinaryString: String = java.lang.Integer.toBinaryString(self)
def toHexString: String = java.lang.Integer.toHexString(self)
diff --git a/src/library/scala/runtime/RichLong.scala b/src/library/scala/runtime/RichLong.scala
index df0bbec047..b405fcda3d 100644
--- a/src/library/scala/runtime/RichLong.scala
+++ b/src/library/scala/runtime/RichLong.scala
@@ -32,6 +32,10 @@ final class RichLong(val self: Long) extends AnyVal with IntegralProxy[Long] {
override def max(that: Long): Long = math.max(self, that)
override def min(that: Long): Long = math.min(self, that)
override def signum: Int = math.signum(self).toInt
+
+ /** There is no reason to round a `Long`, but this method is provided to avoid accidental conversion to `Int` through `Float`. */
+ @deprecated("This is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value?", "2.11.0")
+ def round: Long = self
def toBinaryString: String = java.lang.Long.toBinaryString(self)
def toHexString: String = java.lang.Long.toHexString(self)
diff --git a/test/files/run/t3235-minimal.check b/test/files/run/t3235-minimal.check
new file mode 100644
index 0000000000..d7f716002f
--- /dev/null
+++ b/test/files/run/t3235-minimal.check
@@ -0,0 +1,12 @@
+t3235-minimal.scala:3: warning: method round in class RichInt is deprecated: This is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value?
+ assert(123456789.round == 123456789)
+ ^
+t3235-minimal.scala:4: warning: method round in package math is deprecated: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value?
+ assert(math.round(123456789) == 123456789)
+ ^
+t3235-minimal.scala:5: warning: method round in class RichLong is deprecated: This is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value?
+ assert(1234567890123456789L.round == 1234567890123456789L)
+ ^
+t3235-minimal.scala:6: warning: method round in package math is deprecated: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value?
+ assert(math.round(1234567890123456789L) == 1234567890123456789L)
+ ^
diff --git a/test/files/run/t3235-minimal.flags b/test/files/run/t3235-minimal.flags
new file mode 100644
index 0000000000..dcc59ebe32
--- /dev/null
+++ b/test/files/run/t3235-minimal.flags
@@ -0,0 +1 @@
+-deprecation
diff --git a/test/files/run/t3235-minimal.scala b/test/files/run/t3235-minimal.scala
new file mode 100644
index 0000000000..dc9907b63b
--- /dev/null
+++ b/test/files/run/t3235-minimal.scala
@@ -0,0 +1,8 @@
+object Test {
+ def main(args: Array[String]) {
+ assert(123456789.round == 123456789)
+ assert(math.round(123456789) == 123456789)
+ assert(1234567890123456789L.round == 1234567890123456789L)
+ assert(math.round(1234567890123456789L) == 1234567890123456789L)
+ }
+}