That's most likely because the Double data type is a floating-point number type. And if you have to write e.g. to a target which expects a DECIMAL(16,2), then the Double value will be rounded to 2 fractional digits. But that doesn't mean that the Double value really has a fractional part of 0, only a value "near" 0.
Probably that's the point in your mapping: the Double value may be something like 0.00000056357, and that is not equal to 0.
"Truncating" the Double value to e.g. 4 fractional digits usually won't help because the 4 fractional digits are not accurate either, this is still a floating-point value.
There are basically two things you can do:
Assign the Double value to a DECIMAL(18,2) before the Router and compare this (now rounded) value to 0.0; if it's "equal" to 0.0, then forward NULL through the Router, otherwise forward the DECIMAL value through the Router.
Or you assign the Double value to a String, compare this string to 0.0 and - if equal - forward it as NULL, and then you forward this String value to the target.
That's a "natural" behaviour of floating-point values.