Simple calculation (+,-,*,/,%)

See also: Calculate value, Calculation expression

Value resolver – Abstract

Purpose: This combines several numerical values with one of the four basic arithmetic operations (+,-,*,/ and % for Modulo) to return a scalar result – i.e. a ‘number without a unit’.

images/download/attachments/201667283/image-2025-4-4_14-12-47-version-1-modificationdate-1743768767073-api-v2.png

The Simple calculation (+,-,*,/,%) value resolver combines several numerical values with one of the four basic arithmetic operations in order to return a scalar result – i.e. a 'Number without a unit':

Calculation method
▼ Dropdown selection

Calculation scheme for values
{A, B[, C[, ...]] }

Similar function for aCalculation expression

+

Addition with multiple summands

A + B [+ C [+ ...]]

sum (Addition)

-

Subtraction with a minuend (first value) and one or more subtrahends

A - B [- C [- ...]]

dif (Difference)

*

Multiplication by several factors

A x B [x C [x ...]]

product (Multiplication)

/

Division with a dividend (first value) and one or more divisors

A ÷ B [÷ C [÷ ...]]

quotient (Division)

%

Modulo-Rechnung (ermittelt den "Rest" einer ein- oder mehrstufigen Ganzzahldivision)

A % B [% C [% ...]]

calc (Calculate expression) mit einem Ausdruck wie a % b


List values as input data

Similar to the functions for basic arithmetic operations in calculation expressions (sum(), dif(), product(), quotient()), the Simple calculation (+,-,*,/,%) resolver also accepts lists instead of or in combination with single values as ‘input data’. Furthermore, lists can even be used in a modulo calculation (%).

If value configurations for input data return a list of values, these are ‘resolved’ into individual values and added to the list of all input data:

IMPORTANT◄ Resolving lists affects exactly one level. Individual values are not resolved recursively from nested lists.

Examples:

  • A mixture of single values and lists (described in JSON as: [1,2],[3,4],5,6) is processed using the Subtraction calculation type as dif(1,2,3,4,5,6)and returns the value -19 (=1-2-3-4-5-6).

  • Versucht man die beiden Listenwerte zu einer Liste von Listen bereitzustellen (Beispiel in JSON: [[1,2],[3,4]],5,6) wird eine Subtraktion wie dif(5,6) ausgeführt und das Ergebnis lautet -1 (=5-6).

    • Die eingeschachtelten Listen werden zwar aufgelöst, ergeben aber keinen numerischen Einzelwert sondern $null. Sie werden deshalb übersprungen.

  • Enthält die verschachtelte Liste auch Einzelwerte (Beispiel in JSON: [0,[1,2],[3,4]],5,6) werden diese berücksichtigt. Eine Subtraktion der Beispieldaten berechnet dif(0,5,6) und ergibt -11 (=0-5-6).

NOTE◄ The Calculate value resolver is available for more complex mathematical operations, although it always uses the 'Number with unit' data type (see also Numeric input with unit, Unit conversion) for the result. If the calculation does not result in a unit, a 'Number with unit' is returned without a unit. This is not really a problem, but it can appear cumbersome or confusing. The Simple calculation (+,-,*,/,%) value resolver, on the other hand, delivers a purely numerical result directly and provides a clearer configuration for individual calculation steps with basic mathematical operations. It can also be used to construct 'aggregates' with several calculation steps on the basis of basic arithmetic operations (see examples), although the Calculate value resolver results in a leaner and more transparent configuration if the calculation process is more complex.

Examples

Simple use case (addition): Offset for loop index

In the context of a For each loop, a Show alert event action is executed for each loop pass, which informs the currently processed list value via a 'Message' and names the iteration index in the 'Title', starting at 1. The $index variable provides information about the latter during iteration, although it works with a starting value of 0. This is something machines like. People tend not to. The desired result must therefore be 'converted'. The very simple formula for this is: $input + 1. This task is a clear case for the Simple calculation (+,-,*,/,%) resolver.

Configuration:

The screenshot on the right shows the configuration for a For each loop event action:

  • The Resolver for entities accesses a Variable listOfEntities, via which a 'collection' of entities of an unspecified type is provided as a list. This forms the basis for the iteration in the loop. The action block below expects an entity of undefined type as a reference object for each iteration step.

  • The Show alert event action shown is therefore executed for each entry in the list provided by the listOfEntities variable before further actions follow (here: Dispatch action event).

    • The Title is defined by a Simple calculation (+,-,*,/,%) resolver that uses the Calculation method '+' to request an addition between the value from the variable $index and the integer value 1, which is pre-assigned to the second position in the list of value configurations via an integer value resolver by default. The Output Datatype selected is 'Integer', as the added list values are also of this type.

    • The Object property name is accessed here for the Message, which can contain the specific entity type provided but is not mandatory.

  • A Custom action event with the name SYNCH is then triggered in the context of the iteration, the purpose of which will not be explained in detail here.

images/download/attachments/201667283/image-2024-9-3_15-2-21-version-1-modificationdate-1743686943249-api-v2.png

Simple use case (subtraction): 'Countdown' – iteration index in reverse gear

As in the previous example, a list of entities provided by the variable listOfEntities is processed in a loop.

Unlike the previous case, the Title of the notification issued for each iteration step should no longer display the sequence number of the iteration step (ascending from the value 1), but a 'countdown', i.e. an indication of the number of remaining iterations, which indicates the value 0 in the last step.

Configuration:

The 'countdown' can be achieved within the For each loop by forming the difference between two automatically provided 'loop variables' for each iteration step:

  • $length → Integer value for the total number of iteration steps

  • $index → Integer value for the current iteration index (ascending from the value 0)

In order for the countdown to display the value 0 in the last iteration, the fixed value 1 must be subtracted from the $length value in addition to the $index.

The total calculation to be performed for each iteration step is therefore: $length - $index - 1

The screenshot on the right only shows the value configuration for the Title parameter in the Show alert event action. The surrounding configuration can be copied unchanged from the previous example.

  • '-' (subtraction) is selected here as the Calculation method for the Simple calculation (+,-,*,/,%) resolver.

  • 'Integer' is again selected as the Output Datatype, as is appropriate for a subtraction of integers.

  • The first value configuration defines the minuend for the subtraction, i.e. the output value to be reduced. A Variable value resolver reads the $length value here.

  • All of the following value configurations define subtrahend, i.e. values that are to be subtracted from the minuend:

    • A Variable resolver reads the $index value as a subtrahend.

    • An Integer resolver defines the fixed value 1 as a subtrahend.

images/download/attachments/201667283/image-2024-9-4_8-36-25-version-1-modificationdate-1743686943247-api-v2.png

NOTE◄ Although the 'Countdown' count in the Title runs backwards due to the conversion, the entries in the listOfEntities are processed forwards unchanged. Reversing the direction for the iteration requires a little more effort, as the For each loop event action only iterates forwards. If the countdown index is calculated using the Simple calculation (+,-,*,/,%) resolver and stored in a variable, the name of this variable can be addressed in the 'Offset' parameter of a list item value resolver in order to retrieve the List item matching the displayed index.

More complex use case (subtraction and division): Calculating the 'age' of a company account

As an example of the possibility of creating an aggregate with different calculation operations from several instances of the Simple calculation (+,-,*,/,%) value resolver, the 'age' of a specific company account in years is determined here.

  • The 'age' of an entity is considered to be the time span between the creation date (created property) and the current system time (Relative date with time with the 'Now' type).

  • As time spans are always primarily determined as a millisecond difference, they must then be converted into the target unit (here: years) by division (by 'milliseconds per year').

  • We calculate the duration of a year in milliseconds as 1000 ms/s x 3600 s/h x 24 h/d x 365.25 d/y = 31557600000 ms. Switching days are therefore 'apportioned' at a flat rate of 0.25 days per year.

Configuration:

The screenshot on the right shows a value resolver chain that returns the 'age' of the Company of session in years as a double decimal number:

  • The Company of session resolver at the beginning of the chain provides the company account from the context of the value resolver chain as an input value for the concatenated Simple calculation (+,-,*,/,%) resolver. If value configurations process an input value within the calculation, the company account also applies as an input value for these.

  • The outer Simple calculation (+,-,*,/,%) value resolver defines the conversion from milliseconds to years using the Calculation method '/' (division) with the Output Datatype 'Double':

    • The first value configuration defines the dividend, i.e. the value that is divided by the subsequent divisors. This is determined here by the inner Simple calculation (+,-,*,/,%) instance as the difference between two millisecond values:

      • '-' (subtraction) is selected as the Calculation method and 'Long' as the Output Datatype.

      • The first value configuration reads the 'date value' from a Relative date with time resolver with the 'Now' (NOW) type, which is a Long value by definition, as the minuend.

      • The second value configuration reads the Object property 'Creation date' (created) from the company account as a subtrahend, which is also used as the input value for the internal calculation. By definition, this is a Timestamp value that must be converted into a numerical value (here: Long) using the concatenated Input object (type safe) value resolver.

    • The other value configurations define the divisors for the unit conversion in the outer Simple calculation (+,-,*,/,%) instance. For the sake of transparency, the step-by-step conversions (see above) were randomly adopted as individual divisors instead of using just one divisor with the static total value (31557600000).

images/download/attachments/201667283/image-2024-9-5_9-51-35-version-1-modificationdate-1743686943244-api-v2.png

NOTE◄ Below is a configuration with the Calculate value resolver with the same content for comparison:

In contrast to the Simple calculation (+,-,*,/,%) value resolver, the value configurations for input values must be integrated into the calculation via arbitrarily named variables (now, created).

The variables can then be used directly together with static values to formulate the calculation (top right in the screenshot).

In order to finally obtain the pure numerical value from the calculation result, which is formally generated as a 'Unit number', the Object property 'Value' (value) must be explicitly accessed.

The direct comparison shows that the Calculate value resolver can already map the required 'aggregate' more compactly and clearly in this not yet too complex use case than the comparable configuration with two nested Simple calculation (+,-,*,/,%) instances in the example above.

With the number of calculation steps to be aggregated, a configuration that nests Simple calculation (+,-,*,/,%) instances increases disproportionately, so that the advantage of a 'calculation expression' that names input data as variables and places them in a relationship defined as an 'overall approach' becomes increasingly clear.

Similarly, for a Calculation expression, it should be considered whether the functions sum (Addition), dif (Difference), product (Multiplication) and quotient (Division) should be used for aggregates based on the basic arithmetic operations instead of calc (Calculate expression) with an overall approach.

images/download/attachments/201667283/image-2024-9-5_14-8-2-version-1-modificationdate-1743686943242-api-v2.png

More complex use case (multiplication): Calculate product of efficiencies

A list with a limited number of Double values from the value range [0,1] is provided in an efficiencyFactors variable, which are to be multiplicatively concatenated as efficiencies in order to determine an overall efficiency.

Specific numerical example:

  • Specifically, the value of the efficiencyFactors variable in JSON format could look like this: [0.9, 0.95, 0.75]

  • This results in an overall efficiency of (0.9 x 0.95 x 0.75 = 0.64125).

Configuration:

In a Calculation expression, the list value from the variable could be processed directly in the product (Multiplication) function. Accordingly, $product($var(efficiencyFactors)) would be a target-oriented calculation expression.

As the Simple calculation (+,-,*,/,%) value resolver – as briefly mentioned in the footnote above – cannot process list values directly, the direct translation of the calculation expression into a corresponding value configuration fails.

The following approach demonstrates what a 'multiplicative concatenation' could look like for up to five factors:

The screenshot on the right shows a value resolver chain that starts with the list of individual efficiencies from the Variable efficiencyFactors.

  • The Simple calculation (+,-,*,/,%) value resolver receives the list of efficiencies as an input value.

  • The Calculation Method selected is '*' (multiplication) in conjunction with the Output Datatype 'Double'.

  • Five value configurations are created below, each with a List item value resolver according to the scheme shown for the first two:

    • The Mode is always 'Get first'.

    • The Offset is assigned in ascending order starting at 0, so that up to five values (with Offset 0 to 4) can be read from the input value.

If the list contains fewer than five values in the input value, some of the List item value resolvers return 'No value' ($null). Empty values are simply skipped in the calculation so that all non-empty values are concatenated as required.

images/download/attachments/201667283/image-2024-9-5_15-42-53-version-1-modificationdate-1743686943230-api-v2.png

NOTE◄ The approach described above only fulfills the task if the maximum number of factors can be sufficiently limited in advance. A predetermined number of factors, on the other hand, cannot be processed. It makes little sense to cover a large number of list values in this way if they are only rarely required. The following alternative avoids this restriction.

Alternative Konfiguration:

Der Screenshot rechts zeit eine Wertauflöserkette, an deren Anfang wieder die Liste der einzelnen Wirkungsgrade aus der Variable efficiencyFactors steht.

Die Liste wird bei diesem Ansatz als Eingabewert an den verketteten Simple calculation (+,-,*,/,%)-Wertauflöser übergeben:

  • Als Rechenart ist unverändert "*" in Verbindung mit dem Ausgabe-Datentyp "Double" ausgewählt.

  • Die erste Wert-Konfiguration verwendet einen Object property-Wertauflöser ohne Datenfeldpfad, der die komplette Liste aus dem Eingabewert, des Wertauflösers als Eingabedaten zurückgibt.

  • Die zweite Wert-Konfiguration ist hier überflüssig, da alle zu verrechnenden Einzelwerte als Liste bereitgestellt werden. Ohne eine Wert-Konfiguration wird der Parameter ignoriert. Es kann allerdings nicht entfernt werden, da die Konfiguration eine Mindestanzahl von zwei Wert-Konfigurationen vorsieht.

images/download/attachments/201667283/image-2025-4-4_14-21-25-version-1-modificationdate-1743769285219-api-v2.png

ANMERKUNG◄ Der Zugriff auf die Variable efficiencyFactors könnte hier auch direkt anstelle des Object property-Wertauflösers innerhalb der Berechnung erfolgen. Die Variante im Screenshot soll aber verdeutlichen, dass eine Liste von Eingangsdaten für die Berechnung als Eingabewert per Verkettung bereitgestellt werden kann. Bei Bedarf kann dann innerhalb der Berechnung auch ein Collect values-Wertauflöser verwendet werden, z. B. um Eingangsdaten aus einer Liste von komplexen Objekten zu extrahieren.

Komplexerer Anwendungsfall (Addition & Modulo): Container-Beladung

Eine Variable shipments stellt eine Liste mit Daten zu Sendungen bereit, die unter anderem das Gewicht jeder Sendung im Feld item_kgs angibt.

Deise Sendungen sollen für einen gemeinsamen Transport auf typgleiche Container verladen werden, deren maximale Zuladung eine weitere Variable kgs_per_container spezifiziert.

Unter der Annahme, dass die Stückelung der Sendungen eine Vollauslastung aller verwendeten Container bis auf einen zulässt, soll das Gewicht für die Teilladung berechnet werden, die diesem "letzten" Container theoretisch zufällt.

Konfiguration:

Der Screenshot rechts zeigt eine Wertauflöserkette (s. Chained resolver), die ausgehend von der Liste der Sendungsdaten in der Variable shipments die Berechnung der theoretischen "Teilladung" vornimmt:

  • Der verkettete Simple calculation (+,-,*,/,%)-Wertauflöser verwendet die Rechenart "Modulo" (%) und spezifiziert den Ausgabe-Datentyp BigDecimal.

    ANMERKUNG◄ Der Begriff Ganzzahldivision für die Modulo-Rechnung bedeutet nicht, dass die Eingangsdaten oder der Rückgabewert ganzzahlig sein müssen. Der ermittelte Restwert kann ebenso Dezimalen beinhalten, wie die als Dividend und Divisor angegeben Zahlenwerte. Lediglich die Anzahl der Vielfachen des Divisors, die vom Dividend "subtrahiert" werden, um den Restwert zu ermitteln, ist ganzzahlig. Die Ganzzahl selbst taucht in der Berechnung allerdings nicht auf.

  • Der Dividend wird durch eine weitere Instanz des Simple calculation (+,-,*,/,%)-Wertauflösers durch Aufsummieren der Sendungsgewichte in der Variable shipments ermittelt:

    • Der Collect values-Wertauflöser stellt eine Liste mit den die Gewichtsangaben je Sendung aus dem Object property item_kgs in der "Listenzeile" zusammen.

    • Die zweite Wert-Konfiguration bleibt ungenutzt, weil nur die Listenwerte addiert werden sollen.

  • Den Divisor für die Aufteilung des Gesamtgewichts auf Container stellt die Variable kgs_per_container bereit. der enthaltene Wert definiert die maximale Nutzlast je Container.

  • Der Rückgabewert aus der Berechnung quantifiziert den "Überschuss" an Sendungsgewicht, der zurückbleibt, wenn der letzte "volle" Container beladen ist. Dieser Wert wird per Store value as variable ein eine Variable excess_kgs geschrieben.

images/download/attachments/201667283/image-2025-4-4_14-22-16-version-1-modificationdate-1743769336326-api-v2.png