⚠️ The Kotlin Multiplatform division-by-zero trap #996
Kotools Admin
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
If you write Kotlin Multiplatform code that involves integer division, you may have already hit this: the exact same expression behaves completely differently depending on which platform compiles it.
🐛 The problem
Take this innocuous expression:
On JVM and Native, both lines throw an
ArithmeticException. That is the behavior most Kotlin developers expect and design around.On JavaScript, both lines execute without any exception and silently return
0.Here is a concrete illustration drawn directly from the Kotlin test suites for each platform:
Summary table:
12 / 0ArithmeticException012 % 0ArithmeticException0🤔 Why it happens
On Kotlin/JS,
Intvalues are represented as JavaScript numbers, and12 / 0evaluates toInfinitywhile12 % 0evaluates toNaN. Kotlin/JS truncatesIntarithmetic to 32 bits using JavaScript's| 0operator, and per the ECMAScriptToInt32conversion, bothInfinity | 0andNaN | 0evaluate to0— so the division-by-zero result silently becomes0, with no exception thrown.JVM and Native follow Java's long-standing contract: integer division by zero is always an
ArithmeticException.The practical consequence is that any guard you write and test on JVM — a
try/catch(ArithmeticException)or a pre-condition check that relies on an exception — is silently bypassed when the same code runs on JS. No compile error, no warning, just a wrong result.✅ The fix:
Integerfrom Kotools Types 5.1.1The
Integertype in Kotools Types explicitly checks for a zero divisor before delegating to the platform, so bothdivandremthrowArithmeticExceptionconsistently on JVM, JavaScript, and Native.If you prefer to avoid exception handling altogether,
divOrNullandremOrNullreturnnullinstead of throwing:Integeris annotated with@ExperimentalKotoolsTypesApiand will be stabilized in a future release.See also: API reference
🛠️ Adding Kotools Types to your project
Opt in either per call-site with
@OptIn(ExperimentalKotoolsTypesApi::class)or project-wide via the compiler argument:See also: GitHub
💬 Discussion
Have you run into this inconsistency in a real project? How do you currently guard against division by zero in your multiplatform code?
Beta Was this translation helpful? Give feedback.
All reactions