> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arc.cdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Number Formatters

> Formatters for arithmetic operations, numeric comparisons, rounding, and formatting of numeric values in ArcScript.

export const siteNameShort = "Arc";

## Common Number Formatters

The following formatters are the most common number formatters. An example for each formatter is provided for reference.

<Note>The square brackets around the optional parameters of some formatters are not required. They are there to denote that the parameter is optional.</Note>

### add(value)

Adds the input attribute/value to the *value* parameter and returns the result. The default value is `1`.

#### Example

```xml theme={null}
<!-- count the number of loops in an XML document using xmlDOMSearch -->

<arc:set attr="xml.uri" value="[FilePath]" />
<arc:set attr="xml.xpath" value="/Items/test/loop" />

<arc:call op="xmlDOMSearch" in="xml">
  <!-- this code executes for each occurrence of the 'xpath' in the XML document -->
  <arc:set attr="loopCount" value="[loopCount | def(0) | add(1)]" />
</arc:call>
```

### greaterthan(value\[, ifgreater]\[, ifnotgreater])

Returns *true* if the input attribute/value is greater than the *value* parameter, and *false* otherwise.

If *ifgreater* is supplied, that value is returned instead of *true* (if the input is greater than *value*), and if *ifnotgreater* is supplied, that value is returned instead of *false* (if the input is not greater than *value*).

#### Example

```xml theme={null}
<arc:set attr="totalCost" value="[xpath(Items/Order/TotalCost)]" />
<arc:if exp="[totalCost | greaterthan(1000)]">
  <arc:set attr="highValueOrder" value="true" />
</arc:if>
```

### lessthan(value\[, ifless]\[, ifnotless])

Returns *true* if the input attribute/value is less than the *value* parameter, and *false* otherwise.

If *ifless* is supplied, that value is returned instead of *true* (if the input is less than *value*), and if *ifnotless* is supplied, that value is returned instead of *false* (if the input is not less than *value*).

#### Example

```xml theme={null}
<arc:set attr="totalCost" value="[xpath(Items/Order/TotalCost)]" />
<arc:if exp="[totalCost | lessthan(0)]">
  <arc:throw code="1" desc="ERROR: Invalid order total." />
</arc:if>
```

### multiply(value)

Multiplies the input attribute/value with the *value* parameter and returns the result.

#### Example

```xml theme={null}
<!-- find the total cost by multiplying the price and the quantity of a purchased item -->
<arc:set attr="item.price" value="[xpath(lineitem/costperunit)]" />
<arc:set attr="item.quantity" value="[xpath(lineitem/quantitypurchased)]" />
<arc:set attr="item.totalcost" value="[item.price | multiply([item.quantity])]" />
```

### rand(upperBound)

Generates a random integer between 0 and *upperBound*.

This formatter does not modify the input attribute (variable), so no input attribute is required.

#### Example

```xml theme={null}
<!-- add a random number to the end of a filename -->
<arc:set attr="myFilename" value="myfile-[rand(100000)].xml" />
```

## Other Number Formatters

The following formatters are less common than those described in the previous section.

### abs()

Returns the absolute value of the numeric attribute value.

### and(value)

Returns the AND of two values. The values provided on each side must be 1/0, yes/no, or true/false.

* **value**: The boolean value to compare by.

### ceiling()

Returns the smallest integer greater than or equal to a numeric attribute value.

### currency(\[integer\_count])

Returns the numeric value formatted as currency.

* **count**: An optional number specifying how many places to the right of the decimal to display. The default is `2`.

### decimal(\[integer\_count])

Returns the numeric value formatted as a decimal number, with commas to delimit thousands, millions, and so on.

* **count**: An optional number specifying how many places to the right of the decimal to display. The default is `2`.

### div(\[value])

Returns the result of dividing the numeric attribute value by the specified value of the parameter.

* **value**: An optional numeric value to divide the numeric attribute value by. The default is `2`.

### divide(\[value])

Returns the result of dividing the numeric attribute value by the specified value of the parameter.

* **value**: An optional numeric value to divide the numeric attribute value by. The default is `2`.

### expr(expression)

Evaluates a freeform mathematical or logical expression and returns the result. Unlike single-operation formatters such as `lessthan()` or `isequal()`, `expr()` accepts standard comparison and logical operators directly, making it the preferred approach for compound conditions or multi-variable comparisons.

* **expression**: The freeform expression.

#### Supported Operators

| Operator | Description              |
| -------- | ------------------------ |
| `+`      | Addition                 |
| `-`      | Subtraction              |
| `*`      | Multiplication           |
| `/`      | Division                 |
| `%`      | Modulus (remainder)      |
| `<`      | Less than                |
| `<=`     | Less than or equal to    |
| `>`      | Greater than             |
| `>=`     | Greater than or equal to |
| `==`     | Equal to                 |
| `!=`     | Not equal to             |
| `&&`     | Logical AND              |
| `\|\|`   | Logical OR               |

#### Examples

1. **Equivalent chained-formatter and `expr()` approaches for a `<=` check**

   ```
   <!-- Using chained formatters -->
   [a | lessthan([b]) | or([a | equals([b])])]
   <!-- Using expr() -->
   [_ | expr("[a] <= [b]")]
   ```

   ```
   <arc:set attr="order.orderQty" value="5" />
   <arc:set attr="warehouse.stockLevel" value="10" />
   <arc:set attr="result.canFulfill" value="" />

   <arc:if exp="[_ | expr("[order.orderQty] <= [warehouse.stockLevel]")]">
     <arc:set attr="result.canFulfill" value="true" />
   <arc:else>
     <arc:set attr="result.canFulfill" value="false" />
   </arc:else>
   </arc:if>

   <arc:set attr="out.filename" value="order_fulfillment_result.txt" />
   <arc:set attr="out.data" value="canFulfill=[result.canFulfill]" />
   <arc:push item="out" />
   ```

   **Expected Output**

   A file named `order_fulfillment_result.txt` is written with the contents `canFulfill=true`, and the outgoing message header `X-Can-Fulfill` is set to `true`.

2. **Check of `>=`**

   ```
   <arc:set attr="data.score" value="85" />
   <arc:set attr="data.minimum" value="80" />
   <arc:set attr="data.target" value="85" />
   <arc:set attr="data.stretch" value="90" />
   <arc:set attr="_log.info" value="score >= minimum: [ | expr('[data.score] >= [data.minimum]')]" />
   <arc:set attr="_log.info" value=" score >= target: [ | expr('[data.score] >= [data.target]')]" />
   <arc:set attr="_log.info" value="score >= stretch: [ | expr('[data.score] >= [data.stretch]')]" />
   ```

   **Expected Output**

   * `score >= minimum: true`
   * `score >= target: true`
   * `score >= stretch: false`

3. **Compound condition with multiple variables**

   ```
   <arc:set attr="item.price" value="49.99" />
   <arc:set attr="item.minPrice" value="10" />
   <arc:set attr="item.maxPrice" value="500" />
   <arc:set attr="item.priceValid" value="" />

   <arc:if exp="[_ | expr("[item.price] >= [item.minPrice] && [item.price] <= [item.maxPrice]")]">
     <arc:set attr="item.priceValid" value="true" />
   <arc:else>
     <arc:set attr="item.priceValid" value="false" />
   </arc:else>
   </arc:if>
   ```

   **Expected Output**

   `priceValid = true`

4. **Reading values from an XML input file**

   When a Script connector processes an incoming message, the message body is available via `[FilePath]`. The example below shows how to open that input, read values from it using `xpath()`, and then evaluate those values with `expr()`. Given the following input message:

   ```xml theme={null}
   <Order>
     <Quantity>5</Quantity>
     <StockLevel>10</StockLevel>
   </Order>
   ```

   This script reads those values and evaluates whether the order can be fulfilled:

   ```
   <arc:set attr="order.orderQty" value="" />
   <arc:set attr="order.stockLevel" value="" />
   <arc:set attr="result.canFulfill" value="" />

   <arc:set attr="xml.uri" value="[FilePath]" />
   <arc:call op="xmlOpen" in="xml">
     <arc:set attr="order.orderQty" value="[xpath(Order/Quantity)]" />
     <arc:set attr="order.stockLevel" value="[xpath(Order/StockLevel)]" />
   </arc:call>

   <arc:if exp="[_ | expr("[order.orderQty] <= [order.stockLevel]")]">
     <arc:set attr="result.canFulfill" value="true" />
   <arc:else>
     <arc:set attr="result.canFulfill" value="false" />
   </arc:else>
   </arc:if>
   ```

   **Expected Output**

   `canFulfill = true`

<Note>Attributes referenced inside the expression must contain numeric values when using arithmetic or numeric comparison operators. Non-numeric strings can produce unexpected results.</Note>

### floor()

Returns the largest integer less than or equal to the numeric attribute value.

### format(pattern)

Formats a numerical result based on the provided pattern and the platform's behavior.

* **pattern**: The formatting pattern to use.

#### Examples

```
<arc:set attr="tmp" value="$1,440.123" />
[tmp]
<br>
[tmp | format("#.##")]
```

The `tmp` attribute, set to `$1,440.123`, is passed through the `format("#.##")` formatter. The result is **\$1440.12**.

```
<arc:set attr="rnd" value="1055.68" />
[rnd]
<br>
[rnd | format("#.#")]
```

The `rnd` attribute, set to `1055.68`, is passed through the `format("#.#")` formatter. The result is **1055.7**.

### isbetween(integer\_lowvalue, integer\_highvalue\[, ifbetween]\[, ifnotbetween])

Returns *true* (or *ifbetween*) if the attribute value is greater than or equal to the first parameter value, and less than or equal to the second parameter value. Otherwise it returns *false* (or *ifnotbetween*).

* **lowvalue**: The lower bound of the range to check.
* **highvalue**: The higher bound of the range to check.
* **ifbetween**: The optional value returned if the attribute value is greater than or equal to the first parameter value and less than or equal to the second parameter value.
* **ifnotbetween**: The optional value returned if the attribute value is less than the first parameter value or greater than the second parameter value.

### isequal(value\[, ifequal]\[, ifnotequal])

Returns *true* (or *ifequal*) if the attribute value is equal to the parameter value. Otherwise it returns *false* (or *ifnotequal*).

* **value**: The numeric value to compare with the attribute value.
* **ifequal**: The optional value returned if the attribute value is equal to the parameter value.
* **ifnotequal**: The optional value returned if the attribute value is not equal to the parameter value.

### modulus(value)

Returns the modulus of the numeric attribute value divided by the specified parameter value.

* **value**: The number to divide the attribute value by.

### number(value\[, format]\[, locale])

Returns the numeric value formatted as a decimal number. Provides the option to add formatting and locales.

* **format**: An optional decimal number format. The default is `#.00`. You can use the following special characters:

  | Character | Description                                     |
  | --------- | ----------------------------------------------- |
  | `0`       | Digit                                           |
  | `#`       | Digit; zero shows as absent                     |
  | `.`       | Decimal separator or monetary decimal separator |
  | `-`       | Minus sign                                      |
  | `,`       | Group separator                                 |

* **locale**: The locale information. The default is invariant culture or locale, which means that it's not associated with a particular country or region. It accepts language tags (for example, `en`, `fr`, `en-US`, `en-IN`, `fr-FR`, and `zh-CN`).

### or(value)

Returns the OR of two values. The values provided on each side must be 1/0, yes/no, or true/false.

* **value**: The boolean value to compare by.

### percentage(\[integer\_count])

Returns the numeric value formatted as a percentage.

* **count**: An optional number that indicates how many places to the right of the decimal to display.

### pow(\[value])

Returns the numeric attribute value raised to the power specified by the parameter value.

* **value**: An optional power to raise the attribute value to. The default is `2`.

### round(\[integer\_value])

Returns the numeric attribute value rounded to the number of decimal places specified by the parameter.

* **value**: An optional number of decimal places. The default is `2`.
* **rounding\_mode**: Specifies the rounding behavior for numerical operations capable of discarding precision. Accepted values are: `Default`, `ToEven`, `AwayFromZero`, `ToZero`, `ToNegativeInfinity`, `ToPositiveInfinity`. The default rounding strategy used is based on your operating system. .NET uses <a href="https://learn.microsoft.com/en-us/dotnet/api/system.midpointrounding?view=net-6.0" target="_blank">ToEven</a>, and Java uses <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/RoundingMode.html#HALF_EVEN" target="_blank">Half Even</a>.

You can also specify a global `RoundingMode` environment variable and provide one of the `rounding_mode` values as its value. When you do this, {siteNameShort} uses that rounding mode any time a `rounding_mode` has not been explicitly specified in the formatter. To be more specific, {siteNameShort} checks for values in this order:

1. `rounding_mode` input
2. The `RoundingMode` environment variable
3. The default as determined by the operating system, as described above

### sqrt()

Returns the square root of the numeric attribute value.

### subtract(\[value])

Returns the difference between the numeric attribute value and the value specified by the parameter.

* **value**: The optional numeric value to subtract the attribute value by. The default value is `1`.
