Open gjcoram opened 4 months ago
I found that ngspice gets told that the internal node (branch current for the voltage source) can be collapsed. When I dug further in to OpenVAF, I came across the is_zero() function for Literal (in hir_def/src/expr.rs). contrib3 matches
Literal::Int(0) => true,
whereas contrib2 matches
Literal::Float(val) => val.is_zero(),
and, for some reason, val.is_zero() returns true, even though the value is 1.0, which should be non-zero.
If I change that line to
Literal::Float(val) => *val == Ieee64::with_float(0.0),
then contrib2 works properly.
From lib/stdx/src/ieee64.rs:
/// Get the bitwise representation.
pub fn is_zero(self) -> bool {
// IEEE number is zero if mantissa is zero
(self.0 & 0x000FFFFFFFFFFFFF) == 0
}
The problem appears to be that 1.0 has a special IEEE 754 representation, see https://en.wikipedia.org/wiki/IEEE_754-1985#Examples 1.0 is represented by a fractional part that is all zeros, but the exponent is 0111 1111
The module contrib2 (rename attachment contrib2.txt to contrib2.sp) acts like a 0V voltage source in ngspice-42, even though the contribution is 1.0:
Curiously, if I change the contribution to an integer:
as in contrib3.txt, then it works properly.
contrib2.txt contrib3.txt