Fluent Commerce Logo
Docs
Sign In

How to Handle Amount, Scale, and Unscaled Values

Essential knowledge

Author:

Fluent Commerce

Changed on:

9 Dec 2024

Overview

This guide teaches you how to manage large monetary values accurately in Fluent OMS using

`scale`
and
`unscaledValue`
rather than relying solely on floating-point
`amount`
. By following these practices, you’ll learn to configure financial values for invoices and other transactions with precision. Implementing partners benefit from consistent, reliable data, and customers gain accurate, trustworthy financial information—especially when handling large currency amounts.

Key points

  • Avoid floating-point inaccuracies by using
    `scale`
    and
    `unscaledValue`
    for large amounts.
  • Treat
    `unscaledValue`
    and
    `scale`
    as the source of truth for exact monetary values.
  • Adjust
    `scale`
    to handle very large amounts while maintaining precision.
  • For display and reporting, always reconstruct amounts from
    `unscaledValue`
    and
    `scale`
    .

In  Fluent OMS, monetary values are represented using three related fields:

  • amount (Float): A floating-point representation of the monetary value.
  • scale (Int): The number of decimal places that the unscaled value represents.
  • unscaledValue (Int): The integer representation of the amount before decimal placement.

These three fields together are conceptually similar to a

`BigDecimal`
in Java or other languages, which stores values in a high-precision, scale-aware manner. The
`amount`
field alone is provided for convenience but is susceptible to floating-point inaccuracies, especially as the number of digits grows.

  • unscaledValue: This is the raw integer form of the monetary amount before considering the decimal point. For example, if you have 123.45:
    • `unscaledValue`
      might be
      `12345`
      .
  • scale: This indicates how many decimal places are present. Using the above example:
    • `scale`
      would be
      `2`
      because we have two decimal places.
  • amount: This is a floating-point number derived by applying the scale to the
    `unscaledValue`
    :
    • `amount = unscaledValue * 10^(-scale)`
    • Continuing the example,
      `12345 * 10^(-2) = 123.45`
      .

Floating-point numbers (like

`Float`
or
`Double`
in many programming languages) have limited precision. As the magnitude of the number grows, it becomes increasingly difficult to represent exact decimal values. This leads to rounding or representation errors. For currency values, even tiny inaccuracies can be problematic.

Our OMS fields (

`amount`
,
`scale`
,
`unscaledValue`
) are designed so that
`scale`
and
`unscaledValue`
can be used to store and retrieve the exact monetary amount without precision loss, bypassing the limitations of floating-point arithmetic.

For Data Input (Mutations)

  • Option A (High Accuracy Preferred):
    Always provide
    `scale`
    and
    `unscaledValue`
    fields when creating or updating monetary values. This ensures the OMS stores an exact decimal value.
1 mutation {
2
3  updateInvoice(input: {ref: "invoiceRef123", 
4      totalAmount: {unscaledValue: 1234567878, scale: 2, amount: 12345678.78}}) {
5        ref
6        totalAmount {
7        amount
8        scale
9        unscaledValue
10    }
11
12  }
13
14}

Language: json

Name: Example mutation

Description:

Example mutation 

In this example:

  • `unscaledValue`
    = 1234567878
  • `scale`
    = 2
  • Thus, the exact monetary value is 12345678.78. Including the amount is optional if you are primarily relying on unscaled value and scale for precision, but it can be helpful for readability. The system will use the
    `unscaledValue`
    and
    `scale`
    as the source of truth.
  • Option B (Display Only):

    If you must use the
    `amount`
    alone, understand that it may not represent large values accurately. For very large values (generally 7+ digits before the decimal), floating-point inaccuracies are likely. Consider limiting the usage of
    `amount`
    alone to scenarios where perfect accuracy is not critical.

For Data Retrieval

  • When reading values from the OMS, do not rely solely on the
    `amount`
    if you need precision.
  • Use
    `scale`
    and
    `unscaledValue`
    to reconstruct the exact amount:
    `precise_value = unscaledValue * 10^(-scale)`
  • For example, if
    `unscaledValue = 100000087`
    and
    `scale = 2`
    , then:
    `precise_value = 100000087 * 10^(-2) = 1000000.87`
  • Display this calculated value in your UI or use it in downstream calculations for guaranteed accuracy.

Choosing the Right Scale

Select a

`scale`
that matches the smallest currency unit you handle. For most currencies, a scale of 2 (cents, pence) is common. If your currency requires more precision (e.g., 3 decimal places), adjust accordingly.

UI Display Considerations:

  • If the UI is currently displaying the
    `amount`
    directly, you may see rounding issues on large amounts.
  • To ensure the UI displays exact values, transform
    `unscaledValue`
    and
    `scale`
    into a formatted string. This ensures that what the user sees matches the exact intended monetary value, regardless of the internal floating-point representation.

    Example template code :
    `{{currency (divide unscaledValue ( pow 10 scale) _decimalPlaces=scale) currency}}`

Summary 

  • DO provide
    `scale`
    and
    `unscaledValue`
    when accuracy matters—these are your source of truth.
  • DO use
    `scale`
    and
    `unscaledValue`
    to reconstruct the precise monetary value for display and further calculations.
  • DON’T rely solely on the
    `amount`
    for large or critical monetary values, as floating-point inaccuracies can cause rounding issues.
  • CHECK that your chosen
    `scale`
    and
    `unscaledValue`
    fit within the integer range, and consider using different scales to handle very large values.
Fluent Commerce

Fluent Commerce

Copyright © 2024 Fluent Retail Pty Ltd (trading as Fluent Commerce). All rights reserved. No materials on this docs.fluentcommerce.com site may be used in any way and/or for any purpose without prior written authorisation from Fluent Commerce. Current customers and partners shall use these materials strictly in accordance with the terms and conditions of their written agreements with Fluent Commerce or its affiliates.

Fluent Logo