# Overview

The Fixed package allows you to store and perform math on decimal numbers with a fixed scale (fixed no. of decimal places).

All amounts are stored as BigInts to allow precision math to be performed.

## Sponsored by OnePub

Help support Fixed by supporting [OnePub](https://onepub.dev/drive/0b899961-c78e-4f80-9d94-cfbce54832fa), the private dart repository.

OnePub allows you to privately share Dart packages across your Team and with your customers.

Try it for free and publish your first private package in seconds.

| ![](https://269321363-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWuLOAzBD2JrEpcOB3Aq9%2Fuploads%2FHbpyHPcH940nECAUt6t5%2FOnePub.dev%20Logo%20%E2%80%93%20gitbook%20sponsored%20by.svg?alt=media\&token=78b9c68b-6c00-4cee-b0d7-3ccf8f12fc6d) | <p>Publish a private package in five commands:</p><p><mark style="color:green;"><code>dart pub global activate onepub</code></mark></p><p><mark style="color:green;"><code>onepub login</code></mark></p><p><mark style="color:green;"><code>cd \<my package></code></mark></p><p><mark style="color:green;"><code>onepub pub private</code></mark> </p><p><mark style="color:green;"><code>dart pub publish</code></mark></p> |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

### Features

The features of Fixed are:

* Fixed uses a selectable fixed scale (no. of decimal places)
* Fixed provides a builtin formatter and parser `Fixed.format(pattern)`
* Fixed includes a convenience method `Fixed.formatIntl(locale)` which formats the number with the provided locale or the default locale if not provided.
* You can create a Fixed instance from a number sources

```dart
var t1 = Fixed.fromNum(1); /// == 1.00
var t2 = Fixed.fromNum(1, scale: 3); /// == 1.000

var add = t1 + 10;
var multiply = t1 * t2;

var t3 = Fixed.parse("1.23356"); // == 1.23356, scale: 5

if (t1 == t2) // true
{
    print(t1.format('0.##')); // '1.00'
}

```


# Constructors

There are multiple ways you can create a Fixed object

* Fixed.fromInt
* Fixed.fromBigInt
* Fixed.fromDecimal
* Fixed.parse
* Fixed.fromNum

Example 1

```dart
import 'package:decimal/decimal.dart';
import 'package:fixed/fixed.dart';

Fixed.fromInt(1234, scale: 3); // == 1.234

Fixed.fromBigInt(BigInt.from(1234), scale: 3); // == 1.234

final t1 = Fixed.fromDecimal(Decimal.fromInt(1), scale: 2); // == 1.00

final t3 = Fixed.parse('1.234'); // == 1.234, scale: 3

final t3 = Fixed.parse('1.234', scale: 2); // == 1.23, scale: 2

// This is the least desireable method as it can introduce
// rounding errors.
final t2 = Fixed.fromNum(1.234, scale: 3); // == 1.234
```

##


# Scale

The Fixed package stores numbers with a fixed scale (number of decimal places).

If you attempt an operation on two Fixed values with different scales the result will be the larger of the two scales except when doing multiplication.

```dart
final t1 = Fixed.fromInt(12, scale: 1); // == 1.2, scale: 1
final t2 = Fixed.fromInt(2, scale: 2); // == 2.00, scale: 2
final t3 = t1 + t2; // == 2.20, scale: 2

final t3 = t1 * t2; // == 2.40, scale: 3

```

If you multiply two numbers the scale of the result will be the sum of the two scales.

```dart
final t1 = Fixed.fromInt(12, scale: 1); // == 1.2, scale: 1
final t2 = Fixed.fromInt(2, scale: 2); // == 2.00, scale: 2

final t3 = t1 * t2; // == 2.40, scale: 3
```

You can change the scale of a number by creating a new Fixed object using `Fixed.copyWith`.

Example 2

```dart
  final t7 = Fixed.fromNum(1.234, scale: 3); // == 1.234, scale: 3

  /// reduce the scale
  final t8 = Fixed.copyWith(t7, scale: 2); // == 1.23, scale: 2

  /// increase the scale
  final t9 = Fixed.copyWith(t8, scale: 5); // == 1.2300, scale: 5
```


# Parsing

The fixed package allows you to parse strings into a Fixed instance:

```dart
Fixed.parse('1.234', scale: 3);  // == 1.234
```

If you don't pass in the scale then Fixed will determine the scale from the no. of decimal places in the string:

```dart
Fixed.parse('1.2345'); // == 1.2345, scale = 4
```


# Formatting

Fixed allows you to  format numbers to strings.

The following format characters are supported:

```
# - print a digit if present
0 - print a digit if present else 0. Used to pad strings with zeros.
. - print a dot. The invertSeparator parameter controls if this is treated 
       as a decimal place or a group separator.
, - print a comma. The invertSeparator parameter controls if this is treated 
       as a decimal place or a group separator.       
```

Internationally the '.' and ','  characters are used differently.&#x20;

### USA, UK, Australia etc

In countries such as the USA, UK and Australia the '.' (dot) is used as the delimiter between integer and decimal parts of a number whilst the ',' (comma) is used to group thousands.

Eleven Hundred dollars and 22 cents.

```
$1,100.22
```

In Europe and other countries the '.' (dot) and ',' (comma) are reversed:

### Europian countries etc

Eleven Hundred dollars and 22 cents.

```
$1.100,22
```

### Inverting separators

When formating a number you use the 'invertSeparator' argument to control who the separators character are used. By default, the USA, UK and Australia method is used. Pass invertSperator: false to use the European variation.

Example 4

```dart
var t3 = Fixed.fromInt(1234, scale: 3); // == 1.234

t3.format('00.###0'); // == '01.2340'

// format using euro separators
t3.format('00,###0', invertSeparator: true);  // == '01,2340'

var euFormat = Fixed.parse('1.000.000,23', invertSeparator: true, scale: 2);
// Format using a locale
euFormat.formatIntl('en-AUS'); // == '1,000,000.23'

// Format using default locale
euFormat.formatIntl(); // '1,000,000.23'
```


# Performing math

Fixed provides overloads for the full set of mathematical operations.

When performing most mathematical operations the scale of the result is the larger scale of the two operands.

Example:

```dart
final t1 = Fixed.fromNum(1.234: scale: 3);
final t2 = Fixed.fromNum(1.0, scale: 1);

final t3 = t1 + t2; /// == 2.234, scale: 3
```

For multiplication, the resulting scale is the sum of the operands scales e.g.

```dart
final t1 = Fixed.fromNum(0.01, scale:2) * Fixed.fromNum(0.02, scale:2); 
print(t1); //  = 0.0002, scale: 4
```

If you need to change the scale of a number use Fixed.copyWith passing the required scale.

```dart
 Fixed.copyWith(Fixed.fromInt(5, scale: 2), scale: 10);
```

## Operators

The support operators are:

```
*  - multiplication
/  - division
%  - modulus
+  - addition
-  - subtraction
-  - unary minus (e.g. -1)
~/ - truncating division 
```

Example 6

```dart
final t1 = Fixed.parse('1.23'); // = 1.23
final t2 = Fixed.fromInt(100, scale: 2); // = 1.00

t1 + t2; // == 2.23
t2 - t1; // == -0.23
t1 * t2; // 1.2300
t1 / t2; // 1.23
-t1; // == -1.23
```


# Comparison

## Comparison

Fixed supports a full set of comparison operators:

```
== - equals
<  - less than
>  - greater than
<= - less than or equal
>= - greater than or equal
!= - not equal
```

When comparing two Fixed values the two values will first be scaled so that both values have the same scale. The larger scale from the two values will be used.

Example 7

```dart
final t1 = Fixed.fromNum(1.23);
final t2 = Fixed.fromInt(123, scale: 2);
final t3 = Fixed.fromBigInt(BigInt.from(1234), scale: 3);

expect(t1 == t2, isTrue);
expect(t1 < t3, isTrue);
expect(t1 <= t3, isTrue);
expect(t1 > t3, isFalse);
expect(t1 >= t3, isFalse);
expect(t1 != t3, isTrue);
expect(-t1, equals(Fixed.fromInt(-123, scale: 2)));

expect(t1.isPositive, isTrue);
expect(t1.isNegative, isFalse);
expect(t1.isZero, isFalse);

```

Fixed also supports the compareTo method allowing Fixed values to be sorted.

```
expect(t1.compareTo(t2), equals(0));
```


# Storing

## Storing fixed amounts

&#x20;If you need to store or transmit a fixed value we recommend that you store the value as two discrete numbers:

* &#x20;minorUnits
* scale

Both values should be stored as integers. If storing in a database minorUnits may need to be stored in a large int type.

Storing the value using this technique guarantees no precision loss when storing, transmitting or retrieving Fixed decimal values.


