0 multiplied by -1 returns -0.0 (but not in template editor)

Strange thing.
In the template editor, it looks proper (the result is the same for string as above and a number):

But the template sensor works differently:

  template:
    - sensor:
      - name: "Oven Power"
        state: "{{ (states('sensor.oven_power_negative')|float * -1) |round(2) }}"
        device_class: power
        unit_of_measurement: "W"

Do you have any idea why and how to cope with that?

Try using “abs” to get the absolute value (i.e. ...| round(2)... | round(2) | abs).

Thanks, good workaround.

But why does it happen? Should I file a bug?

Signed zero is a fundamental feature of floating point arithmetic, it’s not specific to HA. It is part of the IEEE standard to stabilize certain operations that approach zero from both sides and is related to signed infinity. You’ll have to deal with signed zero anywhere floating point math is used. For comparison purposes all zeroes are equal (-0 == 0 == +0), so it’s mostly a display thing.

See Signed zero.

I understand. but then the template editor in developer tools is inconsistent with the rest of the system.

BTW, using floating point values/arithmetic for recording power, energy, and especially currency is a total miss (due to accuracy problems). There should be a numeric/decimal datatype. But seems there is no such.

Not really, if done right (I don’t know if it is done right in HA though). FP can precisely represent integer numbers up to a certain range (depending on the FP type) and as long as operations are done on those integer parts only, there will be no accuracy issues. 32 bit FP numbers (single precision) can represent non-fractional numbers up to 2^24 with perfect precision, double precision FP (64 bit) can go up to 2^53. I don’t know what Python uses under the hood, but I would suppose (hope) double precision.

And even when using fractional numbers, double precision FP is really really precise in practice, unless you start operating on very large or very small numbers. The real problems come from combining these two number types in single operations. That doesn’t really happen in HA though.

The most fundamental thing to keep in mind with FP is to never compare for equality. Always use an epsilon on comparisons. That’s where most new programmers get into trouble.

image

Yup, that’s expected. The first example just misses some rounding to make things look nice by removing not-so-relevant digits. The second example is perfectly normal for FP math. Never compare an FP number for equality. Instead of a == b, always do something like this: |a - b| < epsilon. That’s just how FP works. Alternatively you can convert the rounded numerical results to strings and compare those (with all caveats that apply to string comparison).

yeah I know it’s expected from floating-point datatypes. And I know exactly why.
It’s the reason why those should be never used for storing and manipulating anything which requires exactness. This is why we have numeric/decimal datatypes invented. For me obvious, since I’m working with currencies for years (yes I saw fp used for storing currencies and it was resulting in huge problems). Don’t know Python and I’m surprised it doesn’t have a numeric/decimal datatype natively.

BTW converting numbers to strings in order to compare them is too much for me.

Python has a decimal number type, as far as I know. But outside of some very specific domains (financial being a notable one), decimal arithmetic is rarely used in programming. I don’t think that HA needs this.