"True" and "False" in a floating point world

In Pictorus, all signals are currently represented as double-precision floating point numbers. Simply put, it means we store all values with sufficient precision to avoid common issues (like round-off and overflow) encountered when using lesser precision. It means our Apps are a little larger than they need to be, but we don't have to deal with overflow and rounding errors. In time we'll add more user control of variable sizing.

Since boolean logic is crucial to computer programming, we need to specify conventions for True and False in this floating-point world. To keep things simple:

When blocks emit a True/False value (i.e. Logical/Comparison blocks)

  • True will always be emitted as exactly 1.0
  • False will always be emitted as exactly 0.0

When comparing block outputs to evaluate "Truthiness"

  • False is defined as exactly 0.0.
  • ANY value other than exactly 0.0 is defined as True (aka 1.0, 1.1, 12345.6789, -30000000, etc etc)

Consider the example below, comparing a sinewave to a constant value zero. When the sinewave is larger, the comparison block emits "1.0", otherwise it emits "0.0":

Comparison Example

Now consider this example, where we try to do a Logical AND between a sinewave and one:

Comparison Example

You might be wondering why the logical block always emits True, even though there should be an instant where the sinewave equals 0.0 and so both signals are not "True".

The reason becomes clear if we zoom in to the moment of zero-crossing, and consider the timestep of our application: Comparison Example

The sinewave crosses 0.0 at the irrational value t=3.14159..., but our app updated at times 3.1 and 3.2. So in both instances, the sinewave was "non-zero" and therefore True.

For situations like these, it can be helpful to use Deadband Blocks to force small values to zero. Also, its generally better to rework your diagrams where possible to lean on "Less/Greater than or equal" type expressions over exactly "Equals" expressions.