## DEV Community

Danilo Assis for Woovi

Posted on • Updated on

# What is a Ledger and Why Floating Points Are Not Recommended?

Portugue Version

## What is Ledger Series

In the realm of financial transactions and ledgers, accuracy is paramount. However, using floating point numbers to represent monetary values can lead to significant issues due to their inherent imprecision. This is why it's crucial to understand the problems with floats and consider alternative approaches.

## Why Floating Points Are Problematic

Floating point numbers are a common way to represent real numbers in computing. However, they are not suitable for precise financial calculations due to rounding errors. Here are a few examples illustrating the issue:

``````console.log(0.1 + 0.2); // Expected: 0.3, Actual: 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // Expected: true, Actual: false
``````

These small inaccuracies can accumulate over many transactions, leading to significant errors in financial records.

## Using Cents or Decimal128

To avoid these pitfalls, it's recommended to represent monetary values in the smallest units (like cents) or use a data type designed for high precision, such as Decimal128 in MongoDB. This ensures that all calculations are exact, maintaining the integrity of financial data.

## Updating the Example to Use Cents

We'll update our previous example to store amounts in cents instead of dollars, ensuring precision in our calculations.

Define the structure of the ledger in MongoDB using cents:

``````{
_id: ObjectId("60c72b2f9b1d8e4d2f507d3a"),
date: ISODate("2023-06-13T12:00:00Z"),
description: "Deposit",
amount: 100000, // Amount in cents
balance: 100000, // Balance in cents
transactionId: "abc123"
}
``````

Function to add a new entry to the ledger and calculate the balance using cents:

``````const { MongoClient } = require('mongodb');

async function addTransaction(description, amount, transactionId) {
const url = 'mongodb://localhost:27017';
const client = new MongoClient(url);

try {
await client.connect();
const database = client.db('finance');
const ledger = database.collection('ledger');

const existingTransaction = await ledger.findOne({ transactionId: transactionId });

if (existingTransaction) {
return;
}

const lastEntry = await ledger.find().sort({ date: -1 }).limit(1).toArray();

const lastBalance = lastEntry.length > 0 ? lastEntry[0].balance : 0;

const newBalance = lastBalance + amount;

const newEntry = {
date: new Date(),
description: description,
amount,
balance: newBalance,
transactionId: transactionId
};

await ledger.insertOne(newEntry);

} finally {
await client.close();
}
}

addTransaction('Deposit', 50000, 'unique-transaction-id-001'); // Amount in cents
``````

Of course, if you are in prod making a change like this one it will need a migration of database. With mongo, this is easier. You can check how we handle this in our blogpost Zero Downtime Database Migrations at Woovi

The goal here is show what you can learn from common mistakes

## Woovi APIs Use Cents

Woovi, a modern financial services platform, utilizes cents in their APIs to ensure precision and avoid the pitfalls of floating-point arithmetic. By doing so, they maintain the accuracy and reliability of financial transactions, which is crucial for both their operations and their customers' trust.

## Conclusion

Implementing idempotency in your ledger system is crucial for maintaining accurate and reliable financial records. By ensuring that each transaction is only recorded once, you can prevent duplicate entries and maintain the integrity of your data.

As we have seen, idempotency is not just a technical detail but a fundamental principle that helps build robust and fault-tolerant systems. Similarly, using cents instead of floating points ensures precise financial calculations. In our next blog post, we will explore more advanced topics in ledger management and how to handle other challenges such as concurrency and eventual consistency.

Stay tuned for more insights into building reliable financial systems!

Visit us Woovi!