ngspice version: ngspice-47 (Homebrew build, macOS 27, Apple Silicon arm64). Same code on pre-master-48 at 75f22a99f.
Summary. A whole-number .options value above INT_MAX (2147483647) is narrowed to INT_MAX without any warning. For rshunt this makes the shunt about 466x too strong at rshunt=1T.
Minimal deck
rshunt narrowing
Vbias high 0 5
.options rshunt=1T
.op
.control
run
print i(vbias)
.endc
.end
Expected: i(vbias) = -5e-12 (5 V / 1e12 Ohm)
Actual: i(vbias) = -2.32831e-09 (= -5 / 2147483647)
.options rshunt= |
i(vbias) |
|---|---|
1G |
-5.00000e-09 (correct) |
3G |
-2.32831e-09 (wrong, narrowed) |
1T |
-2.32831e-09 (wrong, narrowed) |
1000000000000.5 |
-5.00000e-12 (correct, parsed as real) |
An explicit R1 high 0 1T instead of the option also gives the correct -5e-12.
Likely cause (pre-master-48, 75f22a99f):
src/frontend/parser/numparse.c:166 classifies a value as an integer with return (double) (int) val == val;. For val outside the int range, the double-to-int conversion is undefined behaviour in C (C11 6.3.1.4).src/frontend/variable.c:536 then stores var_alloc_num(name, (int) dbl_val, vars); and the value saturates to INT_MAX on arm64.The result depends on the compiler and platform. I only verified it on darwin arm64; x86-64 may behave differently (e.g. INT_MIN). This affects any whole-number option, not only rshunt.
Suggested fix: in ft_numparse, return "integer" only if val >= INT_MIN && val <= INT_MAX (or fabs(val) < 2147483648.0) before the cast, so larger values stay CP_REAL.
Found while comparing an independent simulator against ngspice-47; it explains a 98% .op difference on the deck from bug #737.
Mattia Fiumara
Can't reproduce your findings with pre-master-48 on CYGWIN, MS VC, and macOS. I always get -5e-12. On Windows VS with ngspice-46 or 47 it is o.k as well.
Do you have another input file?