From 6e9333844ee153c4f11c2ffceef76c2769697c2c Mon Sep 17 00:00:00 2001 From: sergeych Date: Tue, 31 Mar 2026 19:13:45 +0300 Subject: [PATCH] support for Decimal.isInfitite and isNan --- docs/Decimal.md | 11 +++++++++++ .../net/sergeych/lyng/obj/ObjDecimalSupport.kt | 6 ++++++ .../sergeych/lyng/stdlib_included/decimal_lyng.kt | 4 ++++ .../kotlin/net/sergeych/lyng/DecimalModuleTest.kt | 15 +++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/docs/Decimal.md b/docs/Decimal.md index 4a4b1e6..f34feef 100644 --- a/docs/Decimal.md +++ b/docs/Decimal.md @@ -166,6 +166,17 @@ assertEquals(2.9, "2.9".d.toReal()) Use `toReal()` only when you are willing to return to binary floating-point semantics. +## Non-Finite Checks + +`Decimal` values are always finite, so these helpers exist for API symmetry with `Real` and always return `false`: + +```lyng +import lyng.decimal + +assertEquals(false, "2.9".d.isInfinite()) +assertEquals(false, "2.9".d.isNaN()) +``` + ## Division Context Division is the operation where precision and rounding matter most. diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjDecimalSupport.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjDecimalSupport.kt index 4513be8..619ea0d 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjDecimalSupport.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjDecimalSupport.kt @@ -94,6 +94,12 @@ object ObjDecimalSupport { decimalClass.addFn("toReal") { ObjReal.of(valueOf(thisObj).doubleValue(false)) } + decimalClass.addFn("isInfinite") { + ObjFalse + } + decimalClass.addFn("isNaN") { + ObjFalse + } decimalClass.addFn("toString") { ObjString(valueOf(thisObj).toStringExpanded()) } diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/stdlib_included/decimal_lyng.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/stdlib_included/decimal_lyng.kt index 34c8886..b44c8b4 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/stdlib_included/decimal_lyng.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/stdlib_included/decimal_lyng.kt @@ -161,6 +161,10 @@ extern class Decimal() { extern fun toInt(): Int /** Convert to `Real`. */ extern fun toReal(): Real + /** Return true if this decimal is positive or negative infinity. Always false for Decimal. */ + extern fun isInfinite(): Bool + /** Return true if this decimal is NaN (not a number). Always false for Decimal. */ + extern fun isNaN(): Bool /** * Convert to a plain decimal string without scientific notation. * diff --git a/lynglib/src/commonTest/kotlin/net/sergeych/lyng/DecimalModuleTest.kt b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/DecimalModuleTest.kt index 08d40ca..cb64e73 100644 --- a/lynglib/src/commonTest/kotlin/net/sergeych/lyng/DecimalModuleTest.kt +++ b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/DecimalModuleTest.kt @@ -51,6 +51,21 @@ class DecimalModuleTest { ) } + @Test + fun testDecimalIsInfiniteAndIsNaN() = runTest { + val scope = Script.newScope() + scope.eval( + """ + import lyng.decimal + + assertEquals(false, 0.d.isInfinite()) + assertEquals(false, "12.34".d.isInfinite()) + assertEquals(false, 0.d.isNaN()) + assertEquals(false, "12.34".d.isNaN()) + """.trimIndent() + ) + } + @Test fun testDecimalModuleMixedIntOperators() = runTest { val scope = Script.newScope()