Report floating point literals exceeding precision
authorDmitry Timofeev <dmitry.timofeev@jetbrains.com>
Tue, 22 Jun 2021 11:02:23 +0000 (14:02 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Tue, 22 Jun 2021 11:06:18 +0000 (11:06 +0000)
Added a new inspection to detect floating point literals in Kotlin code
that exceed the precision of the corresponding type. A quick-fix
replaces these literals with their rounded values.

^KTIJ-9225 Fixed

GitOrigin-RevId: dca7dfeeb65b81d5851be8bbd005c4579266bd87

40 files changed:
plugins/kotlin/idea/resources-en/inspectionDescriptions/FloatingPointLiteralPrecision.html [new file with mode: 0644]
plugins/kotlin/idea/resources-en/messages/KotlinBundle.properties
plugins/kotlin/idea/resources/META-INF/inspections.xml
plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/FloatingPointLiteralPrecisionInspection.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/.inspection [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doublePi11.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding1.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding2.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding3.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding3.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding4.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding5.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding6.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding6.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding7.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding8.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding8.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding9.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding9.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase1.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase1.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase2.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase2.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatLargeInteger.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatLargeInteger.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi6Digits.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi7Digits.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi7Digits.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding1.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding1.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding2.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding2.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding3.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding3.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding4.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding4.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding5.kt [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding5.kt.after [new file with mode: 0644]
plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding6.kt [new file with mode: 0644]

diff --git a/plugins/kotlin/idea/resources-en/inspectionDescriptions/FloatingPointLiteralPrecision.html b/plugins/kotlin/idea/resources-en/inspectionDescriptions/FloatingPointLiteralPrecision.html
new file mode 100644 (file)
index 0000000..7dee982
--- /dev/null
@@ -0,0 +1,28 @@
+<html>
+<body>
+Reports floating-point literals that cannot be represented with the required precision
+using <a href="https://en.wikipedia.org/wiki/IEEE_754">IEEE 754</a> Float and Double types.
+
+<p>
+    For example, <code>1.9999999999999999999</code> has too many significant digits,
+    so its representation as a <code>Double</code> will be rounded to <code>2.0</code>.
+    Specifying excess digits may be misleading as it hides the fact that computations
+    use rounded values instead.
+</p>
+
+<p>
+    The quick-fix replaces the literal with a rounded value that matches the actual representation
+    of the constant.
+</p>
+
+<p><b>Example:</b></p>
+<pre><code>
+  val x: Float = 3.14159265359f
+</code></pre>
+
+<p>After the quick-fix is applied:</p>
+<pre><code>
+  val x: Float = 3.1415927f
+</code></pre>
+</body>
+</html>
index 9a3544b745dc47014668c0a80dd15436e0e2453c..97a210d6a6012a56e519f75107b408f78429f12e 100644 (file)
@@ -2376,5 +2376,9 @@ replace.0.with.1.and.vice.versa=Replace ''{0}'' with ''{1}'' and vice versa
 inspection.kotlin.constant.conditions.display.name=Constant conditions
 inspection.message.condition.always.true=Condition is always true
 inspection.message.condition.always.false=Condition is always false
+
 inspection.message.when.condition.always.true=When branch is always reachable
 inspection.message.when.condition.always.false=When branch is never reachable
+
+floating.point.literal.precision.inspection.display.name=Floating-point literal exceeds the available precision
+floating.point.literal.precision.inspection=Floating-point literal cannot be represented with the required precision
index 2c5689a9766ff513618df678a77ba6f6a48b7d4a..146408064fda8df6c0b47737f61a87e32e9e0baa 100644 (file)
                      language="kotlin"
                      key="inspection.kotlin.constant.conditions.display.name" bundle="messages.KotlinBundle"/>
 
+    <localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.FloatingPointLiteralPrecisionInspection"
+                     groupPath="Kotlin"
+                     groupName="Other problems"
+                     enabledByDefault="true"
+                     level="WEAK WARNING"
+                     language="kotlin"
+                     key="floating.point.literal.precision.inspection.display.name" bundle="messages.KotlinBundle"/>
+
   </extensions>
 
 </idea-plugin>
\ No newline at end of file
diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/FloatingPointLiteralPrecisionInspection.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/FloatingPointLiteralPrecisionInspection.kt
new file mode 100644 (file)
index 0000000..4268f63
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package org.jetbrains.kotlin.idea.inspections
+
+import com.intellij.codeInspection.LocalQuickFix
+import com.intellij.codeInspection.ProblemDescriptor
+import com.intellij.codeInspection.ProblemHighlightType
+import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.openapi.project.Project
+import com.intellij.psi.PsiElementVisitor
+import org.jetbrains.kotlin.idea.KotlinBundle
+import org.jetbrains.kotlin.idea.inspections.dfa.getKotlinType
+import org.jetbrains.kotlin.psi.KtConstantExpression
+import org.jetbrains.kotlin.psi.KtPsiFactory
+import org.jetbrains.kotlin.psi.expressionVisitor
+import org.jetbrains.kotlin.psi.stubs.ConstantValueKind
+import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType
+import org.jetbrains.kotlin.types.typeUtil.isFloat
+import java.math.BigDecimal
+
+/**
+ * Highlight floating point literals that exceed precision of the corresponding type.
+ *
+ * Some floating point values can't be represented using IEEE 754 floating point standard.
+ * For example, the literal 9_999_999_999.000001 has the same representation as a Double
+ * as the literal 9_999_999_999.000002. Specifying excess digits hides the fact that
+ * computations use the rounded value instead of the exact constant.
+ *
+ * This inspection highlights floating point constants whose literal representation
+ * requires more precision than the floating point type can provide.
+ * It does not try to detect rounding errors or otherwise check computation results.
+ */
+class FloatingPointLiteralPrecisionInspection : AbstractKotlinInspection() {
+    private val FLOAT_LITERAL = KtConstantExpressionElementType.kindToConstantElementType(ConstantValueKind.FLOAT_CONSTANT)
+    private val FORMATTING_CHARACTERS_REGEX = Regex("[_fF]")
+
+    override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
+        return expressionVisitor {
+            if ((it is KtConstantExpression) && (it.elementType == FLOAT_LITERAL)) {
+                val isFloat = it.getKotlinType()?.isFloat() ?: false
+                val uppercaseSuffix = isFloat && it.text?.endsWith('F') ?: false
+                val literal = it.text?.replace(FORMATTING_CHARACTERS_REGEX, "") ?: return@expressionVisitor
+
+                try {
+                    val parseResult = if (isFloat)
+                        literal.toFloat().toString()
+                    else
+                        literal.toDouble().toString()
+
+                    val roundedValue = BigDecimal(parseResult)
+                    val exactValue = BigDecimal(literal)
+                    if (exactValue.compareTo(roundedValue) != 0) {
+                        val replacementText = if (isFloat)
+                            parseResult + if (uppercaseSuffix) "F" else "f"
+                        else
+                            parseResult
+
+                        holder.registerProblem(
+                            it,
+                            KotlinBundle.message("floating.point.literal.precision.inspection"),
+                            ProblemHighlightType.WEAK_WARNING,
+                            FloatingPointLiteralPrecisionQuickFix(replacementText))
+                    }
+                } catch (e: NumberFormatException) {
+                    return@expressionVisitor
+                }
+            }
+        }
+    }
+}
+
+private class FloatingPointLiteralPrecisionQuickFix(val replacementText: String) : LocalQuickFix {
+    override fun getName(): String = KotlinBundle.message("replace.with.0", replacementText)
+
+    override fun getFamilyName(): String = name
+
+    override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
+        val element = descriptor.psiElement as? KtConstantExpression ?: return
+        element.replace(KtPsiFactory(element).createExpression(replacementText))
+    }
+}
index ecfebe64dbc9c8576e80c4354729716355110182..34bd318443a12edf6e8a5ec98c246850a2b4197f 100644 (file)
@@ -5139,6 +5139,119 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti
         }
     }
 
+    @RunWith(JUnit3RunnerWithInners.class)
+    @TestMetadata("testData/inspectionsLocal/floatingPointLiteralPrecision")
+    public static class FloatingPointLiteralPrecision extends AbstractLocalInspectionTest {
+        private void runTest(String testDataFilePath) throws Exception {
+            KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
+        }
+
+        @TestMetadata("doublePi11.kt")
+        public void testDoublePi11() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doublePi11.kt");
+        }
+
+        @TestMetadata("doubleRounding1.kt")
+        public void testDoubleRounding1() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding1.kt");
+        }
+
+        @TestMetadata("doubleRounding2.kt")
+        public void testDoubleRounding2() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding2.kt");
+        }
+
+        @TestMetadata("doubleRounding3.kt")
+        public void testDoubleRounding3() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding3.kt");
+        }
+
+        @TestMetadata("doubleRounding4.kt")
+        public void testDoubleRounding4() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding4.kt");
+        }
+
+        @TestMetadata("doubleRounding5.kt")
+        public void testDoubleRounding5() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding5.kt");
+        }
+
+        @TestMetadata("doubleRounding6.kt")
+        public void testDoubleRounding6() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding6.kt");
+        }
+
+        @TestMetadata("doubleRounding7.kt")
+        public void testDoubleRounding7() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding7.kt");
+        }
+
+        @TestMetadata("doubleRounding8.kt")
+        public void testDoubleRounding8() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding8.kt");
+        }
+
+        @TestMetadata("doubleRounding9.kt")
+        public void testDoubleRounding9() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding9.kt");
+        }
+
+        @TestMetadata("floatKeepSuffixCase1.kt")
+        public void testFloatKeepSuffixCase1() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase1.kt");
+        }
+
+        @TestMetadata("floatKeepSuffixCase2.kt")
+        public void testFloatKeepSuffixCase2() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase2.kt");
+        }
+
+        @TestMetadata("floatLargeInteger.kt")
+        public void testFloatLargeInteger() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatLargeInteger.kt");
+        }
+
+        @TestMetadata("floatPi6Digits.kt")
+        public void testFloatPi6Digits() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi6Digits.kt");
+        }
+
+        @TestMetadata("floatPi7Digits.kt")
+        public void testFloatPi7Digits() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi7Digits.kt");
+        }
+
+        @TestMetadata("floatRounding1.kt")
+        public void testFloatRounding1() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding1.kt");
+        }
+
+        @TestMetadata("floatRounding2.kt")
+        public void testFloatRounding2() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding2.kt");
+        }
+
+        @TestMetadata("floatRounding3.kt")
+        public void testFloatRounding3() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding3.kt");
+        }
+
+        @TestMetadata("floatRounding4.kt")
+        public void testFloatRounding4() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding4.kt");
+        }
+
+        @TestMetadata("floatRounding5.kt")
+        public void testFloatRounding5() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding5.kt");
+        }
+
+        @TestMetadata("floatRounding6.kt")
+        public void testFloatRounding6() throws Exception {
+            runTest("testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding6.kt");
+        }
+    }
+
     @RunWith(JUnit3RunnerWithInners.class)
     @TestMetadata("testData/inspectionsLocal/foldInitializerAndIfToElvis")
     public static class FoldInitializerAndIfToElvis extends AbstractLocalInspectionTest {
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/.inspection b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/.inspection
new file mode 100644 (file)
index 0000000..6f32a12
--- /dev/null
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.inspections.FloatingPointLiteralPrecisionInspection
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doublePi11.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doublePi11.kt
new file mode 100644 (file)
index 0000000..aaeb4c2
--- /dev/null
@@ -0,0 +1,4 @@
+// WITH_RUNTIME
+// PROBLEM: none
+
+val pi = <caret>3.14159265359
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding1.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding1.kt
new file mode 100644 (file)
index 0000000..41ced77
--- /dev/null
@@ -0,0 +1,4 @@
+// WITH_RUNTIME
+// PROBLEM: none
+
+val x = <caret>0.1
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding2.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding2.kt
new file mode 100644 (file)
index 0000000..47dda2d
--- /dev/null
@@ -0,0 +1,4 @@
+// WITH_RUNTIME
+// PROBLEM: none
+
+val x: Double = <caret>0.100
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding3.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding3.kt
new file mode 100644 (file)
index 0000000..0e57cc4
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = <caret>9_999_999_999.000001
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding3.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding3.kt.after
new file mode 100644 (file)
index 0000000..e2caa4b
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = 9.999999999000002E9
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding4.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding4.kt
new file mode 100644 (file)
index 0000000..e82a09c
--- /dev/null
@@ -0,0 +1,4 @@
+// WITH_RUNTIME
+// PROBLEM: none
+
+val x = <caret>9_999_999_999.000002
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding5.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding5.kt
new file mode 100644 (file)
index 0000000..1865e58
--- /dev/null
@@ -0,0 +1,4 @@
+// WITH_RUNTIME
+// PROBLEM: none
+
+val x = <caret>1.000000000000001
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding6.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding6.kt
new file mode 100644 (file)
index 0000000..cb522ed
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = <caret>1.0000000000000001
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding6.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding6.kt.after
new file mode 100644 (file)
index 0000000..4a4c082
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = 1.0
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding7.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding7.kt
new file mode 100644 (file)
index 0000000..da701de
--- /dev/null
@@ -0,0 +1,4 @@
+// WITH_RUNTIME
+// PROBLEM: none
+
+val x = <caret>1.0000000000000002
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding8.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding8.kt
new file mode 100644 (file)
index 0000000..4fcb8a1
--- /dev/null
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo(x: Double): Double = x * 2.0
+
+val z = foo(<caret>1.9999999999999999)
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding8.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding8.kt.after
new file mode 100644 (file)
index 0000000..f53f13f
--- /dev/null
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo(x: Double): Double = x * 2.0
+
+val z = foo(2.0)
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding9.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding9.kt
new file mode 100644 (file)
index 0000000..6d9b171
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = <caret>9999999999999999.1
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding9.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/doubleRounding9.kt.after
new file mode 100644 (file)
index 0000000..66930a6
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = 1.0E16
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase1.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase1.kt
new file mode 100644 (file)
index 0000000..76c43fc
--- /dev/null
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun test(): Float {
+    return <caret>0.123456789f
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase1.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase1.kt.after
new file mode 100644 (file)
index 0000000..ed07020
--- /dev/null
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun test(): Float {
+    return 0.12345679f
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase2.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase2.kt
new file mode 100644 (file)
index 0000000..4a6711a
--- /dev/null
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun test(): Float {
+    return <caret>0.123456789F
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase2.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatKeepSuffixCase2.kt.after
new file mode 100644 (file)
index 0000000..03e0876
--- /dev/null
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun test(): Float {
+    return 0.12345679F
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatLargeInteger.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatLargeInteger.kt
new file mode 100644 (file)
index 0000000..301c3e7
--- /dev/null
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun test() {
+    val x = <caret>9_999_999_999f
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatLargeInteger.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatLargeInteger.kt.after
new file mode 100644 (file)
index 0000000..4e6ef3a
--- /dev/null
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun test() {
+    val x = 1.0E10f
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi6Digits.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi6Digits.kt
new file mode 100644 (file)
index 0000000..5844f5f
--- /dev/null
@@ -0,0 +1,4 @@
+// WITH_RUNTIME
+// PROBLEM: none
+
+val pi = <caret>3.141593f;
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi7Digits.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi7Digits.kt
new file mode 100644 (file)
index 0000000..f860c33
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val pi = <caret>3.1415926f;
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi7Digits.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatPi7Digits.kt.after
new file mode 100644 (file)
index 0000000..9067631
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val pi = 3.1415925f;
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding1.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding1.kt
new file mode 100644 (file)
index 0000000..67db1af
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x: Float = <caret>1.00000000000000001f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding1.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding1.kt.after
new file mode 100644 (file)
index 0000000..94b1e5e
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x: Float = 1.0f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding2.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding2.kt
new file mode 100644 (file)
index 0000000..7e1b398
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = <caret>1.00000000000000002f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding2.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding2.kt.after
new file mode 100644 (file)
index 0000000..a34fd5b
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = 1.0f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding3.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding3.kt
new file mode 100644 (file)
index 0000000..74e57a3
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = <caret>1.9999999999999999999999999999999f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding3.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding3.kt.after
new file mode 100644 (file)
index 0000000..96c9e9d
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = 2.0f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding4.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding4.kt
new file mode 100644 (file)
index 0000000..48099d0
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = <caret>9_999_999_999.000001f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding4.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding4.kt.after
new file mode 100644 (file)
index 0000000..ee6570b
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = 1.0E10f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding5.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding5.kt
new file mode 100644 (file)
index 0000000..c2a8db6
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = <caret>9_999_999_999.000002f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding5.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding5.kt.after
new file mode 100644 (file)
index 0000000..ee6570b
--- /dev/null
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+val x = 1.0E10f
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding6.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/floatingPointLiteralPrecision/floatRounding6.kt
new file mode 100644 (file)
index 0000000..09b227b
--- /dev/null
@@ -0,0 +1,4 @@
+// WITH_RUNTIME
+// PROBLEM: none
+
+val x = <caret>0.100000000000000000000f