From 08052c19ebe44006285d360c58dc284f22a1e228 Mon Sep 17 00:00:00 2001 From: "n8n-cat-bot[bot]" <283985454+n8n-cat-bot[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2026 11:01:16 +0000 Subject: [PATCH] fix: Handle exponential-notation numbers in smartDecimal (#35967) Co-authored-by: n8n-cat-bot[bot] Co-authored-by: Claude Opus 4.8 --- .../@n8n/utils/src/number/smart-decimal.test.ts | 17 +++++++++++++++++ packages/@n8n/utils/src/number/smart-decimal.ts | 6 ++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/@n8n/utils/src/number/smart-decimal.test.ts b/packages/@n8n/utils/src/number/smart-decimal.test.ts index 07360cd7572..3c6ab07907f 100644 --- a/packages/@n8n/utils/src/number/smart-decimal.test.ts +++ b/packages/@n8n/utils/src/number/smart-decimal.test.ts @@ -32,4 +32,21 @@ describe('smartDecimal', () => { it('should round to two decimal if it is smaller than the given one', () => { expect(smartDecimal(42.56, 3)).toBe(42.56); }); + + it('should round exponential-notation numbers to zero at the default decimals', () => { + // `0.0000001` stringifies to `"1e-7"` (no decimal point) + expect(smartDecimal(0.0000001)).toBe(0); + }); + + it('should round exponential-notation numbers correctly at higher precision', () => { + expect(smartDecimal(0.0000001, 8)).toBe(0.0000001); + }); + + it('should round negative exponential-notation numbers to zero', () => { + const result = smartDecimal(-0.0000001); + // `Number((-0.0000001).toFixed(2))` yields `-0`. `toBe(0)` uses `Object.is` + // and would fail on `-0`, so assert value equality with `===`, which treats + // `-0 === 0` as `true` — the -0 pitfall. + expect(result === 0).toBe(true); + }); }); diff --git a/packages/@n8n/utils/src/number/smart-decimal.ts b/packages/@n8n/utils/src/number/smart-decimal.ts index 2682e570ecd..38f8c80a0d7 100644 --- a/packages/@n8n/utils/src/number/smart-decimal.ts +++ b/packages/@n8n/utils/src/number/smart-decimal.ts @@ -4,8 +4,10 @@ export const smartDecimal = (value: number, decimals = 2): number => { return value; } - // Check if it has only one decimal place - if (value.toString().split('.')[1].length <= decimals) { + // Check if it has only one decimal place. Exponential-notation numbers + // (e.g. `0.0000001` → `"1e-7"`) have no `.`, so fall through to rounding. + const decimalPart = value.toString().split('.')[1]; + if (decimalPart !== undefined && decimalPart.length <= decimals) { return value; }