From a262aaba15effce48fdba95910bef367f89cafca Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Tue, 17 Jan 2017 01:32:05 -0800 Subject: SI-10148 Follow Java for float literals Use `Float.parseFloat` instead of converting from Double. Error when a value rounds to zero. --- .../scala/tools/nsc/ast/parser/Parsers.scala | 4 +-- .../scala/tools/nsc/ast/parser/Scanners.scala | 34 ++++++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index cf66e0a7dc..d7d0f01741 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1263,8 +1263,8 @@ self => case CHARLIT => in.charVal case INTLIT => in.intVal(isNegated).toInt case LONGLIT => in.intVal(isNegated) - case FLOATLIT => in.floatVal(isNegated).toFloat - case DOUBLELIT => in.floatVal(isNegated) + case FLOATLIT => in.floatVal(isNegated) + case DOUBLELIT => in.doubleVal(isNegated) case STRINGLIT | STRINGPART => in.strVal.intern() case TRUE => true case FALSE => false diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index a8cc7f91c2..ccd0d4a9c9 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -972,23 +972,45 @@ trait Scanners extends ScannersCommon { def intVal: Long = intVal(negated = false) - /** Convert current strVal, base to double value + /** Convert current strVal, base to float value. */ - def floatVal(negated: Boolean): Double = { - val limit: Double = if (token == DOUBLELIT) Double.MaxValue else Float.MaxValue + def floatVal(negated: Boolean): Float = { try { - val value: Double = java.lang.Double.valueOf(strVal).doubleValue() - if (value > limit) + val value: Float = java.lang.Float.parseFloat(strVal) + if (value > Float.MaxValue) syntaxError("floating point number too large") + val zeroly = "0.fF" + if (value == 0.0f && strVal.exists(c => !zeroly.contains(c))) + syntaxError("floating point number too small") if (negated) -value else value } catch { case _: NumberFormatException => syntaxError("malformed floating point number") + 0.0f + } + } + + def floatVal: Float = floatVal(negated = false) + + /** Convert current strVal, base to double value. + */ + def doubleVal(negated: Boolean): Double = { + try { + val value: Double = java.lang.Double.parseDouble(strVal) + if (value > Double.MaxValue) + syntaxError("double precision floating point number too large") + val zeroly = "0.dD" + if (value == 0.0d && strVal.exists(c => !zeroly.contains(c))) + syntaxError("double precision floating point number too small") + if (negated) -value else value + } catch { + case _: NumberFormatException => + syntaxError("malformed double precision floating point number") 0.0 } } - def floatVal: Double = floatVal(negated = false) + def doubleVal: Double = doubleVal(negated = false) def checkNoLetter(): Unit = { if (isIdentifierPart(ch) && ch >= ' ') -- cgit v1.2.3