Math / Text

AppBuilder is all about building a data field based on a math formula. Here's the math symbols and operations you can use in your formula.

Quick Start

Numbers

Decimals and integers can be used in formulas:  e.g. 5, 1.8432, -2

Null/Blank Values

null is a special value which means data is undefined, blank, or missing (e.g. HR monitor not connected). Math operations on null result in null. Dividing by zero results in null. Null is displayed as "--" or "--:--".

Functions that take averages, min or max all ignore nulls.

Arithmetic operations (plus, minus, multiply, divide) on null always result in null. Comparisons with null are always false (unless you compare null to null).

For some formulas you may wish to treat null as zero:

[AppBuilderClassic]: if (hr eq null, 0, hr)
[AppBuilder5]: alt(hr , 0)

More Information

Math Operators

(Operators are not case-sensitive. "AND" is the same as "and")
OperatorDescription
+, plusAddition, join text
-Subtraction
*Multiplication
/Division
^Power/exponentiation
( )Grouping, function call
divInteger division
mod, %Remainder
;Separate expressions (X ; Y = Y)
=, eqEquals
!=, neqNot equals
andLogical and
orLogical or
lt, <Less than
lte, <=Less than or equals
gt, >Greater than
gte, >=Greater than or equals

Boolean Logic

AppBuilder supports boolean logic (conditional logic with true/false values):
  • 0 and NULL are false, anything else is true
  • Logical operators give a result of 1 for true, and 0 for false

Strings/Text [AppBuilder5] [CIQ2]

You can use strings of text in your formula if you want to add prefixes, suffixes or display short messages. A string is enclosed in single quotes or double quotes. e.g.
'Hello world'
"bpm"

I recommend using single quotes, because double quotes may not work in the iOS version of Garmin Connect Mobile.
Note that only "straight" quotes are supported: ' "
"Smart" curly quotes and apostrophes won't work: ‘ ’ “ ”

If your phone wants to type smart apostrophes/quotes, hold down the key until you can select the straight quote.

Working with text and numbers

e.g. Join text with +:
'Hello ' + 'world'

e.g. Join text and numbers with +:
hr + 'BPM'
26.2 + ' miles' → '26.2 miles'
123 + "" + 45 → "12345"

Once you combine a number with text, it becomes text and can no longer be used for calculations or FIT recording. To get around this problem, the RECORD() function is available. It records a value to the FIT file, then returns the same value for further use.

e.g. Record HR and join it with text
record(hr) + ' bpm'

Formatting numbers

Numbers that are joined with text are automatically formatted using app settings (auto, number, decimal, pace or time). If you need more control over the format, or you have a couple of numbers to format individually, several functions exist to help you.

The following functions will format a number in the same way as the Display Format app settings: formattime, formattime2, formatnumber, formatdecimal, formatpace

e.g. Display pace and HR in the same field
formatpace(speed) + ':' + formatnumber(hr)

NOTE: To get text to display in the largest font possible, use only the following characters:
[AppBuilder5] (no spaces allowed):
0123456789:.
[AppBuilder5+] (spaces are allowed):
#%+-./0123456789:°
If you want even more control, there's the FORMAT function, which lets you use a format string to specify how you want to display a number.

e.g. Format speed with one decimal place:
format(speed, '%.1f')
Please refer to the Garmin documentation for more information on the format string, which is similar to a "printf-style" format string. Please note that due to platform limitations, the app may just crash if the format string is invalid.

Once you format a number, it becomes text and can no longer be used for calculations or FIT recording. Use the RECORD() function to get around this problem:
e.g. Record speed to FIT and format it with 1 decimal place:
format(record(speed), '%.1f');

e.g. Record HR to FIT and display Speed with 1 decimal place:
record(hr); format(speed, '%.1f');

Text and Functions

The following functions and operators work with text:
+ ; if ifs alt setv getv

In other contexts, strings will be treated as null (blank).

Details

Examples

9 / 4 = 2.25
9 div 4 = 2
9 mod 4 = 1
10.5 div 2.5 = 4
10.5 mod 2.5 = .5
2 ^ 2 ^ 3 = 2 ^ (2 ^ 3) = 256
1 eq 2 = 0
1 eq 1 = 1

X ; Y = Y
e.g. Alert at 16 miles and show remaining distance to 16 mile mark [CIQ2] 
alert(distance gte 16); 16 - distance

Logical Operators

  • Logical operators are used for comparing two values. They return 1 for a true comparison and 0 for false.
  • Combined with functions, operators allow you to make simple decisions about what to display or calculate (see examples below)
  • Relational operators: Equals, not equals, less than, greater than, less than or equal to, greater than or equal to. In your formula, use:
    eq, neq, lt, gt, lte, gte
    • e.g.
      1 eq 2 = 0
      1 eq 1 = 1
      1 lt 5 = 1
  • and
    x and y returns 1 if both x and y are true, 0 otherwise
    (Note: both x and y are always evaluated)
  • or
    x or y returns 1 if either x or y are true, 0 otherwise
    (Note: both x and y are always evaluated)

Null (blank) values

Sometimes it is important to distinguish between 0 and "null" (blank, undefined or unknown).

For example:
- A grade of 0 means you are on level ground, but a grade of null means the grade is unknown.
- If your HR monitor is not connected (and your wrist HR is off/not being worn), then your HR is null, not 0.
- I assume that other sensors (such as Power) would return null for dropouts, but I haven't tested any power meters.

AppBuilder deals with null in ways which hopefully make sense when you are dealing with physical quantities:
  • Null is displayed as "--" or "--:--" (time/pace formats)
  • eq and neq will work as expected when you compare things to null.
    • null eq null = 1 (null equals null)
    • null neq 0 = 1 (null doesn't equal 0)
  • For logical comparison functions, NULL is treated the same as FALSE (0). (if(), or(), and(), not(), when(), alert())
    • null or 5 = 1
    • null and 5 = 0
    • not(null) = 1
    • if (null, 10, 20) = 20
  • avg(), min() and max() ignore null values
  • Dividing by zero returns null:
    • 5 / 0 = null
    • 0 / 0 = null
  • Any other operation with numbers on NULL yields another NULL. (i.e. If one of your variables is unknown, then your entire formula is unknown.)
    e.g.
    • 5 + null = null
    • 5 * null = null
    • 5 - null = null
    • null / 5 = null
    • 5 < null = null
  • Joining NULL with text is a little different:
    • 180 + "/" + null = "180/--"
      (if the display format is Auto/Number)
    • 180 + "/" + null = "180/--:--"
      (if the display format is Time/Pace)
Any of this behaviour can be overridden by using explicit comparisons. For example:
  • Treat null the same as 0, in the formula "5 + hr"
    5 + if (hr eq null, 0, hr)
    Or with [AppBuilder5]:
    5 + alt(hr, 0)

Appendix

Operator Precedence

Operators are listed from highest to lower precedence. Operators on the same level are either applied left-to-right or right-to-left, depending on their associativity:

Example of left-to-right associativity: X + Y + Z = (X + Y) + Z
Example of right-to-left associativity: X ^ Y ^ Z = X ^ (Y ^ Z)
OperatorDescriptionAssociativity
^Power / exponentiationRight-to-left
* / mod divMultiplication, division, remainder, integer divisionLeft-to-right
+ -Addition, subtractionLeft-to-right
lt, lte, gt, gteLess than, less than or equal to, Greater than, greater than or equal toLeft-to-right
eq, neqEqual to, not equal toLeft-to-right
andLogical andLeft-to-right
orLogical orLeft-to-right
;Semicolon (separate expressions)Left-to-right
,Comma (separate function arguments)Left-to-right
Note: Function calls have higher precedence than any operator
Note: Parentheses (other than function calls) can be used to group sub-expressions; expressions within parentheses are evaluated from inner to outer.

e.g. 5 / (2 * (8 - 3))
8 - 3 is evaluated first, resulting in 5
Then 2 * 5, resulting in 10
Then 5 / 10, resulting in 0.5

Notes

div is defined as follows: x div y = floor(x/y)
mod is defined as follows: x mod y = x - y * floor(x/y)

Comments