Skip to content

Instantly share code, notes, and snippets.

@darksylinc
Last active October 15, 2025 19:00
Show Gist options
  • Select an option

  • Save darksylinc/861b494f1f18dbc765b0bbd627a5d4f0 to your computer and use it in GitHub Desktop.

Select an option

Save darksylinc/861b494f1f18dbc765b0bbd627a5d4f0 to your computer and use it in GitHub Desktop.
Accounting Explanation for Programmers

Back when I was studying the Double Entry (DE) system felt like "why why why?" because it felt like an overly-complicated way of performing transaction and storing financial records. But now I feel like it's something that can't be missing.

Also take in mind that Double Entry was invented 400 years before computers. However even with computers, it's still useful for its properties of guaranteeing transactions make sense.

The best way to explain it from a programmer perspective is CRC and Error Check Codes.

Imagine we had to store a value in ECC RAM, but we have to manually calculate the ECC bits.

For the sake of simplicity I'm going to deviate a bit from how real RAM works, and assume the following:

  1. Our RAM can only store 8-bit values.
  2. Instead of using regular ECC, we store an 8-bit value of CRC-8.
  3. We can do math on RAM directly, and on the ECC too.

So image I have to store the value 0x05 to RAM. Its CRC is 0x2E. If I were to write 0x15 to RAM but with CRC = 0x2E, it'd be an error.

ECC is doing its job by ensuring the value can't be altered unless it makes sense.

Now we want to subtract 1 from our records. So we'd do:

0x05 - 0x01 = 0x04

BUT! Now the CRC wouldn't match. Because our record says 0x04 but CRC 0x2E doesn't match.

The CRC-8 for 0x04 is 0x01 The solution is to do math on the CRC directly as an atomic operation:

0x05 - 0x01 = 0x04
0x2E - 0x2D = 0x01

NOW it matches! The important key that I want to highlight is that there is a unique mathematical way to ensure the transaction is correct:

  1. If I want to subtract 0x01 from 0x05; I MUST subtract 0x2D from 0x2E
  2. I can obtain the value 0x2D (an unknown) mathematically.

OK now that I've explained this, the Double Entry isn't as complex as calculating a CRC, but it's more like RAID1 that keeps an extra copy (Until it isn't, more on that later)

So the way DE works is that we have a Debit and a Credit columns. AND THEY MUST MATCH. We say they're balanced. Let's start a company with USD 100.000 of cash:

Movement Type Debit Account Credit Account Debit # Credit #
Ai Cash 100.000
Ei Equity 100.000

Note

Ai stands for Asset increase.

Ei stands for Equity increase.

So you may notice that we increased Cash by 100.000. However the dumbfounding part is the Equity. Basically it is its counterpart, aka RAID1. The sum of all transactions in the debit column must be equal to the sum of all transactions of the Credit column. This is extremely similar to a CRC check.

Now let's say our company asks a $150.000 loan from the Bank:

Movement Type Deb Account Credit Account Debit # Credit #
Ai Cash 150.000
Li Bank Loans 150.000

Note

Li stands for Liability increase.

If we were to check our balance, it would look like this:

Type Deb Account Cred Account Debit Credit
Asset Cash 250.000
Liability Bank Loans 150.000
Equity Equity 100.000

Notice that it's no longer "RAID1" in the sense that we do not store a duplicate of Cash, but rather it's more like RAID5 error codes because we must ensure that Bank Loans + Equity = Cash.

And now let's buy a car for $20.000 with our cash:

Movement Type Deb Account Credit Account Debit # Credit #
Ai Vehicles 20.000
Ad Cash 20.000

Note

Ad stands for Asset decrease.

If we see the balance it would now be:

Type Deb Account Cred Account Debit Credit
Asset Cash 230.000
Asset Vehicles 20.000
Liability Bank Loans 150.000
Equity Equity 100.000

Notice that 230.000 + 20.000 == 150.000 + 100.000.

It's also important to notice the following:

Type Sign of Transaction Always goes in the column:
Asset increase Debit
Asset decrease Credit
Liability increase Credit
Liability decrease Debit
Equity increase Credit
Equity decrease Debit

For example, if you see an Asset decrease on the Debit column, it's wrong. There are also other guarantees. For example the "Cash" account can never be negative (However some Asset accounts can be negative, such as Bank Accounts if they overdrafted, or Depreciation accounts. I won't go into Depreciation. Just be aware that as a general rule Assets being negative is like a code smell, but there are cases where it's allowed).

OK but WHY?!

So, in the world of computers this may seem archaic and unnecessary. All a computer needs to do is:

json["Cash"] = 230.000;
json["Vehicles"] = 20.000;
json["Bank Loans"] = 150.000;
json["Equity"] = 100.000;

And you don't really care about Double Entry or the type of account it is like Liability or EQuity. Real ECC RAM and RAID5 takes care of integrity and we call it a day!

Well, that's true in the sense of data integrity and when it comes to simple examples (and assuming your code doesn't have bugs like an integer underflow or a rounding error that gives you infinite money!).

But Double Entry helps a lot in complex situations where you're not sure how much you owe to the IRS.

For example:

  • You sold $100k in merchandise.
  • Your inventory stock at the beginning of the year is $150k
  • Your inventory stock at the end of the year is $120k
  • Your purchases throughout the year has been $30k
  • How much do you owe the IRS? (let's assume a tax flat of 30%).

Let's analyze it with the Double Entry:

Type Deb Account Cred Account Debit Credit
Ai Cash 150.000
Ed ??? ???
Ad Inventory Stock ???
Ei Sales 150.000

We know we got 150.000 in cash. Thus our sales must have been 150.000. But what the hell about the rest?

So how much Inventory Stock did we sell? Ok let's see:

  • Your inventory stock at the beginning of the year is $150k (we know this, because it was in our last year's report)
  • Your inventory stock at the end of the year is $120k (we know this, thanks to an inventory audit we did on 30th December)
  • Your purchases throughout the year has been $30k (we know this, thanks to our supplier's data or from their receipts)
  • We don't know how many units we sold (the idiot who was supposed to track this and enter the sales on the system forgot it)

That means we must have sold:

what_we_had + purchases - costs = what_we_have_now
150k + 30k - costs = 120k
costs = 150k + 30k - 120k
costs = 60k

So we sold 60k in inventory stock. Whether some of our employees actually stole half of that, or it was thrown away because it got stale, or all of it was sold to customers, we'll never know. Because reality is imperfect and that registry was not logged (we may assume a fixed % to certain types of losses based on statistical averages from other data, but let's keep it simple).

So:

Type Deb Account Cred Account Debit Credit
Ai Cash 150.000
Ed ??? ???
Ad Inventory Stock 60.000
Ei Sales 150.000

We're almost there!

The other "???" account that is missing is the Equity account called "Cost of Merchandise". And by difference Double Entry, we know how much it is, and now it becomes obvious:

Type Deb Account Cred Account Debit Credit
Ai Cash 150.000
Ed Cost of Merch 60.000
Ad Inventory Stock 60.000
Ei Sales 150.000

Notice that the IRS is conceptually interested in the Equity accounts:

 (Sales - Cost of Merchandise) x 30% = 90.000 x 30% = 27.000

So we owe $27.000 to the IRS.

But what was the point? We could have figured it out by doing:

 Cash - Inventory Stock

Uh, no. Conceptually, that makes no sense. Why are you subtracting your inventory stock to a cash transaction? So if someone lends you money you're going to pay taxes to the IRS?! If you buy more stock that means you pay less taxes? It is very error prone.

Once complex international operations involving lots of purchases and sales and profits and losses; the Double Entry separates the flow of physical goods and services (like cash, bank transactions, and goods) from purely-abstract concepts like profits and losses.

Yes, profits and losses are abstract concepts because if you got $100 extra in your hand that doesn't mean you had $100 profit. Maybe someone lent it to you. But if you got it because you won the lottery, then it was indeed a profit.

Thus, the Double Entry is still very useful for conceptual reasoning and error checking wrong lines of thought.

Likewise if your code contains an error and now suddenly your system says you've got 4294967000 in cash, Double Entry acts as an extra check because the Debit & Credit columns will not match (they're unbalanced).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment