[HN Gopher] Things I learned while developing a billing system
       ___________________________________________________________________
        
       Things I learned while developing a billing system
        
       Author : arnon
       Score  : 147 points
       Date   : 2021-04-05 17:03 UTC (5 hours ago)
        
 (HTM) web link (arnon.dk)
 (TXT) w3m dump (arnon.dk)
        
       | loop0 wrote:
       | I went through the same issues 6 years ago, had to create the
       | entire billing system from scratch, and there are so many corner
       | cases I had to deal with, specially with plan changes on
       | recurring subscriptions, had to deal with world wide timezones
       | for the invoice creations and lots of other stuff. I just wish
       | there was a pluggable, robust and flexible solution to use
       | instead of reinventing the wheel.
        
       | epa wrote:
       | All of these features are fairly basic and routine and should
       | have been part of scoping. The issue is that engineers rarely
       | speak to finance teams to gather input which leads to these
       | 'surprises'. The article is equivalent to "how hard could it be
       | to win my lawsuit, i researched the law".
        
         | encoderer wrote:
         | Ok, genius, you go write a blog post then.
        
           | yellowyacht wrote:
           | > Ok, genius, you go write a blog post then.
           | 
           | That was unnecessarily antagonistic
        
             | encoderer wrote:
             | Totally disagree. I came here for commentary on the blog
             | post not a cliche HackerNews trope. When I replied, his was
             | the top comment. Honestly, guys like that need a nudge
             | every now and again to train their filter. A downvote just
             | isn't enough. Welcome to the community.
        
         | spelunker wrote:
         | To be fair, this blog is apparently written by a product
         | manager, who presumably discovered these features by doing
         | research. And probably asking finance teams.
        
           | arnon wrote:
           | Accurate
        
       | [deleted]
        
       | kube-system wrote:
       | > Store money including the smallest possible subdivisions.
       | 
       | > For example:
       | 
       | > $100 US may be stored as 10000
       | 
       | Eh, the US dollar is often subdivided further than that.
       | 
       | Here's four examples, in different industries:
       | 
       | http://cdn.radioiowa.com/wp-content/uploads/2011/12/gas-pump...
       | 
       | https://aws.amazon.com/s3/pricing/
       | 
       | https://finance.yahoo.com/u/yahoo-finance/watchlists/most-ac...
       | 
       | https://www.digikey.com/en/products/detail/microchip-technol...
        
         | kbenson wrote:
         | Those are unit prices or interval prices. Any transaction will
         | almost definitely be in an amount of dollars and centers if
         | dealing in US, rounding to a whole cent based on the total
         | units or interval.
         | 
         | For example, if you're paying #3.089 a gallon at the pump, and
         | you pump exactly one gallon, you don't pay $3.089, you'll pay
         | $3.09, and neither your account or the account you're paying
         | into will need to know or care about the tenth of a cent
         | difference, because our monetary system doesn't really deal
         | with denominations that small in transactions.
        
           | deckard1 wrote:
           | yeah but this is where you really have to be careful where
           | you do your rounding.                 3.089 * 10,000 = 30890
           | 3.09 * 10,000 = 30900
           | 
           | A one cent rounding added up to $10 difference. It's easy to
           | screw this up in code, sending values to databases or across
           | APIs, etc.
           | 
           | Also reminds me of the plot of Office Space. Which is a bit
           | humorous since they screwed up their own scamming scheme in
           | similar fashion.
           | 
           | https://www.youtube.com/watch?v=yZjCQ3T5yXo
        
       | mr-wendel wrote:
       | My personal favorite: how long is a month?
       | 
       | - _An even 30 days_ = Easy to explain and do math with. Adding
       | /subtracting 1 month can leave you in the same month or skip
       | February entirely! Anniversary dates bounce around from month-to-
       | month. Maps poorly to yearly calculations.
       | 
       | - _However many days >this< month has_ = Harder to explain and do
       | math with. Months without 31 days can get skipped when
       | adding/subtracting 1 month. Recurring events get pushed away from
       | the end of the month to cluster around the beginning of the
       | month. It does result in a steady anniversary date for edge
       | cases.
       | 
       | - _Closest numeric day, but prev /next month_ (e.g. Jan 31 -> Feb
       | 28): Easy _and_ hard to explain and do math with. It 's great for
       | ensuring events only ever happen once per calendar month, but
       | adds extra ambiguity (e.g. Jan 31 > Feb 28 > March 30? ... or
       | March 28th?)
       | 
       | - _30.4..._ = Just no... except for the few times this is right
       | and you need consistency to avoid unfairly comparing 28 days vs
       | 31 days.
       | 
       | The consequence is some very surprising things the first time you
       | see them. Some billing systems simply avoid doing work past the
       | 28th of each month (either doing it a bit early or a bit late).
       | Some just embrace the weirdness (whichever you flavor you pick)
       | and you get used to the quirks (e.g. end-of-month lulls and
       | start-of-month spikes).
        
         | sk5t wrote:
         | I'll unwaveringly go with whatever the hardass valid-date-
         | enforcing mechanisms in java.time and PostgreSQL enforce.
         | 
         | Add a month to the epoch time? Can't do it because that doesn't
         | adequate indicate what day we think it is. "select
         | '2021-01-30'::date + make_interval(months := 1)" says Feb 28?
         | Done!
        
           | throwawayboise wrote:
           | Absolutely. Go with the date/time/interval functions that
           | your database or language libraries provide. Do not try to
           | reinvent this, you will get it wrong 10 times before you get
           | it right.
        
           | arnon wrote:
           | My go-to for everything is WWPD - "What would Postgres do?"
        
         | tzs wrote:
         | If I ever get to redesign the billing system at work, I'm going
         | to go with fixed day of the month billing. We currently do 30
         | day billing, and most customers are fine with that, but there
         | are some who need their bill to not come the same week as their
         | rent is due, or not come until after they receive their monthly
         | pension payment, or something like that. Right now we have to
         | have special handling for those people.
         | 
         | For handling the different lengths between the months, I've
         | considered a few approaches.
         | 
         | 1. If re-bill is supposed to be the Nth of each month, that
         | simply means N-1 days after the 1st. If that falls into another
         | calendar month, fine. So if someone asks to be billed on the
         | 30th of each month, they will be billed on Jan 30th for
         | January, Mar 2nd for February, Mar 30 for March, and so on. I'd
         | make sure the receipt explicitly says "Re-bill for January",
         | "Re-bill for February", etc., so that bill the see on Mar 2nd
         | hopefully will not confuse them, nor will seeing another bill
         | later that month.
         | 
         | 2. If re-bill is supposed to be on the 29th-31st, for February
         | it takes place on the 28th (29th in leap years). For other
         | months, if re-bill is supposed to be on 31st, it takes place on
         | the 30th in April, June, September, and November.
         | 
         | 3. If you initially order on day 1-21 of the month, your re-
         | billing is the same day ever month. If you initially order on
         | day 22+, your re-billing is on the same number of days before
         | the end of the month as was your initial order. For example,
         | someone who orders on May 30th would re-bill on the 30th in 31
         | day months, the 29th in 30 days months, and the 27th in
         | February (28th in leap years). If you ask for a change in fixed
         | billing date, you can do so either as Nth day of the month or
         | Mth day from the end of the month, but N or M must be <= 28.
        
           | PeterisP wrote:
           | For additional fun, consider how this would work with the
           | added constraint of needing the date be a business day, so
           | you need to take into account how weekends (which vary across
           | the world, by the way; in a bunch of countries sunday is a
           | business day but friday is off) and banking holidays in every
           | locale in which you do business.
        
             | notimpotent wrote:
             | First time learning that weekend days vary by country. I
             | looked up [1] some of the more curious ones.
             | 
             | Brunei weekends are Friday and Sunday. Those poor folks
             | work Mon-Thurs, and then go back to work Saturday!
             | 
             | [1] https://en.wikipedia.org/wiki/Workweek_and_weekend
        
               | thaumasiotes wrote:
               | For reference, in China there are a bunch of legally
               | mandated holidays that convert the weekend days around
               | them into normal working days. (The conversion is not
               | legally mandated; think of it as a response to laws that
               | generate many more holidays than the economy supports.)
        
           | thaumasiotes wrote:
           | > For handling the different lengths between the months, I've
           | considered a few approaches.
           | 
           | > 1. If re-bill is supposed to be the Nth of each month, that
           | simply means N-1 days after the 1st.
           | 
           | I have a credit card that takes the much simpler approach
           | "Your payment due date is the Nth of each month. N can be any
           | value from 1 to 24."
           | 
           | This seems to basically match your approach 3.
           | 
           | If you ask how I think you should bill ( :p ), do it on a
           | fixed day and don't try to do rebilling at a fixed interval.
           | If the day somebody buys your thing is unsuitable for fixed-
           | date billing, the answer is prorating their first period, not
           | interval billing.
        
           | arnon wrote:
           | > If I ever get to redesign the billing system at work, I'm
           | going to go with fixed day of the month billing.
           | 
           | This may have unintended consequences. Some examples we faced
           | around this:
           | 
           | 1. Stress on our APIs when 15,000 invoices are created in the
           | span of a couple of minutes. We had to build more queueing
           | mechanisms around this. Some services just can't handle more
           | than 100 calls a second.
           | 
           | 2. Getting rate limited by MasterCard
           | 
           | 3. Some payment providers thinking we're brute-forcing them
        
             | virtue3 wrote:
             | Aren't all of these handled by a queue and some reasonable
             | sense of going through it slowly? (I can just say that on
             | the internet, I know designing it that way is not exactly
             | trivial).
        
               | arnon wrote:
               | Not all systems have sane defaults or queues built-in.
               | 
               | I'm just saying this needs consideration when you reach a
               | certain scale.
        
           | mr-wendel wrote:
           | If you ever get to... GET TO? You must love pain! Actually, I
           | wonder what business you're coding for to have those be
           | important criteria and wish you all the best of luck!
           | 
           | In general, however:
           | 
           | Don't fall victim to one of the classic dev blunders -- the
           | most famous of which is "don't roll your own crypto" -- but
           | only slightly less well-known is this: "Never write your own
           | billing logic when business is on the line!"
        
         | paulclinger wrote:
         | Maybe if the date is "close" to the end of the month (as in
         | fewer than X days from the end of the month), then count in the
         | days left, so Jan 31st (0 days left) becomes Feb 28th and then
         | to Mar 31st and so on.
        
         | vidanay wrote:
         | This is why I've never understood why payroll is commonly on
         | the 15th and last days of the month. Why not 1st and 15th?
         | Those dates never change.
        
           | pc86 wrote:
           | In my experience 1/15 is no less common than 15/L or every
           | two weeks.
        
         | gergely wrote:
         | These use cases are also "fun" if you add timezones as well
         | into the mix!
        
           | deckard1 wrote:
           | _shudder_
           | 
           | I can only imagine needing to toss in standard/daylight
           | timezone switch in there. Billing code really is the pinnacle
           | of developer pain. It mixes the arbitrariness of special case
           | business and customer rules with the absolute horror of time
           | and date math.
        
             | pc86 wrote:
             | Not only that but in T-SQL, `AT TIME ZONE` takes DST into
             | account but not in the names. So something like:
             | SELECT CreatedDate AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern
             | Standard Time' FROM MyTable
             | 
             | would in fact return `CreatedDate at Easter _Daylight_ Time
             | if executed today.
        
       | sorbits wrote:
       | I would base anything dealing with money on a double entry
       | accounting system.
       | 
       | The issues that arise are then a question about how to translate
       | them to journal entries, which will require accounting
       | experience, and maybe your chart of accounts needs to be revised,
       | but the core system should be fairly stable, and voiding an
       | invoice by issuing a credit note comes automatically, as you're
       | working with an append-only ledger.
       | 
       | The issues about prepaid plans should also be handled, as
       | payments for services not rendered yet should not be recognized
       | as income, but instead kept as a liability: The OP mentions their
       | system is used by 15,000 customers, so I would give each customer
       | their own account (in the chart of accounts).
       | 
       | The main technical issue is what datatype to use for money, the
       | rest are problems solved by following general accounting
       | principles, though I fear that a lot of programmers out there are
       | reinventing the wheel (in suboptimal ways).
        
         | throwawayboise wrote:
         | > payments for services not rendered yet should not be
         | recognized as income, but instead kept as a liability
         | 
         | This entirely depends on whether you are operating on a cash or
         | accrual basis. Both approach are valid (at least in the USA)
         | and cash basis is often used by small businesses.
        
           | sorbits wrote:
           | I use the word "should" as per RFC 2119, i.e. recommended (as
           | opposed to "must" = required).
           | 
           | Though the IRS does limit the types of businesses that can do
           | cash-basis accounting, it would be businesses without
           | inventory, and who does not offer credit to their customers,
           | e.g. a hairdresser would probably use cash-basis accounting,
           | but more complicated businesses would not, certainly not a
           | business that needs its own billing system :)
        
       | gerikson wrote:
       | Obligatory: https://blog.plover.com/prog/Moonpig.html
        
         | arnon wrote:
         | Thanks for that! I haven't seen this...
         | 
         | I'm glad to see he also has the same thought about floating
         | points. Also:
         | 
         | > Happily, Moonpig did not have to deal with multiple
         | currencies. That would have added tremendous complexity to the
         | financial calculations, and I am not confident that Rik and I
         | could have gotten it right in the time available.
         | 
         | This is one of the things we deal with which is quite
         | challenging.
        
       | kjrose wrote:
       | Having worked on billing and accounting systems for decades now.
       | I am constantly amazed by all of the edge cases and situations
       | that have to be handled to ensure that every bill is correct and
       | nothing is missed or misbilled. Especially since the oil firms
       | out here will reject an invoice if it is off by as little as a
       | penny.
       | 
       | At first it seems like it's so easy and straightforward but when
       | you are looking at thousands if not millions of bills a year and
       | the myriad methods you need to compensate for to ensure its
       | accepted by large firms.... well. I can say nothing surprises me
       | anymore. Including hardware level errors causing an issue no one
       | expected with a final number.
        
         | cosmodisk wrote:
         | The principles behind it all are pretty simple and well
         | established. What makes it complicated are the people and
         | poorly designed systems.
        
         | throwawayboise wrote:
         | Right -- accounting seems simple. It's just debits and credits
         | and adding it all up. Until you get into it, and you understand
         | why "Accounting" can easily be a department of dozens or
         | hundreds of people.
        
           | kjrose wrote:
           | There's a reason to separate your accounts receivable from
           | payables. To separate invoicing from receipts.
           | 
           | And so on and so on. You don't realize it until you suddenly
           | realize why it was such a bad idea to have one point of
           | failure for everything.
        
       | ehutch79 wrote:
       | There are absolutely time when you need to deal with amounts
       | smaller than the smallest division of a currency.
       | 
       | For example: 1 ea @ $0.00589 Normally this is when ordering in
       | the thousands or millions of small things, but you need to record
       | that fractional size.
        
         | Kiro wrote:
         | Yeah, this immediately broke my idea of only dealing with cents
         | and integers. All of a sudden I wanted to price something
         | $0.001 and it all came crashing down.
        
       | canada_dry wrote:
       | Here's a lesson (I can laugh about now that I'm retired): one of
       | the first billing systems I ever wrote (in the 90's) had invoices
       | with a mask of '$ZZ,ZZ9.99' based on interviews with staff. About
       | a year later I get an urgent call from the owner. It seems a
       | client was under-billed about $100K dollars due to truncated
       | invoice.
       | 
       | Subsequently, whenever interviewing clients for requirements I'd
       | mention this and it usually resulted in padding their specs.
        
       | pfranz wrote:
       | One edge-case I've noticed with Apple's subscription billing and
       | heard other people talk about when implementing billing systems
       | is changing currencies/countries. Apple, in line with most
       | people's expectations, when you cancel a subscription it doesn't
       | cancel immediately and prorate a refund. It just stops future
       | billing and lets you serve out your remaining cycle (gyms and
       | other meatspace places do this). The problem is you then have to
       | wait until your subscription expires to transfer your account to
       | a new country/currency.
        
       | breischl wrote:
       | My favorite: when do you do rounding?
       | 
       | For instance, with proration. Take each line item, prorate it,
       | round it, then add them all together. Totally reasonable.
       | 
       | Now add all the line items together, prorate the total, and round
       | it. Also reasonable, but there's a decent chance the number is
       | different by a few pennies because of rounding differences. If
       | you chained more calculations the differences would compound.
       | 
       | Whichever way you choose, somebody is going to whip out their
       | calculator and tell you that you did it wrong (but only when they
       | come out better the other way).
       | 
       | This applies anywhere you're doing multiplication or division.
       | Discounts, proration, taxes, "cashback", "store credit dividend",
       | whatever.
        
         | ianmcgowan wrote:
         | In my world, we keep a running total of the rounded prorated
         | amounts, and then the last item (n) becomes (total - total up
         | to n-1) to make sure amounts match. It can still be a problem
         | if the last value is very small however.
        
       | unixhero wrote:
       | Billing is very hard. That is why systems like Geneva is used.
        
       | mmcconnell1618 wrote:
       | Another fun use case is when a customer is charged for their
       | invoice via credit card and then 60 days later, you get a
       | chargeback from the bank. Now you have to unwind the previous
       | invoices and entitlement systems to figure out if you should
       | fight the chargeback, cancel the subscription or some other non-
       | standard process.
        
       | berkes wrote:
       | In my last financial product we added 'bitcoin' and 'festival
       | tokens' as currencies in the backend. At first for fun.
       | 
       | But we found out the client devs (web, mobile apps) had severe
       | difficulties and wanted it removed. Turned out they all
       | implemented currencies wrong. Either with hardcoded decimals or
       | with localised in and outputs that would break if a client
       | changed their locales.
       | 
       | So now, my favorite best practice for any financial data handling
       | is that: ensure your system can handle Bitcoin (8 decimal places)
       | and festival tokens (missing currency symbol, zero decimals).
       | Anywhere this leads to trouble is a red flag and will probably
       | cause trouble later on. Now at least you are aware.
        
         | michael1999 wrote:
         | That's great advice. I'll add it to my list of round-tripping
         | German, and Japanese text with emojis, and changing the
         | timezone.
        
           | arthurcolle wrote:
           | What do you mean by round tripping German here?
           | 
           | I think I get the issues with the other two, but curious
           | about the first thing!
        
             | dan-robertson wrote:
             | Not sure about round tripping but perhaps the longer words
             | might stress test webpage layouts.
        
             | [deleted]
        
         | [deleted]
        
       | brixon wrote:
       | "Whatever limitations you plan for, plan for how to bypass them
       | too. This will happen."
       | 
       | The world is not straightforward, allow an admin to fix/change
       | anything and when they get tired of making some change then code
       | that new path in the system. Working with or writing systems that
       | do not allow admin overriding is painful.
        
       | bidirectional wrote:
       | > A common wisdom in database design is "never using floating-
       | point numbers for money"
       | 
       | Common, and in my experience totally wrong. It's the most
       | pervasive cargo culting I've experienced amongst developers,
       | where people with 0 experience with financial applications will
       | recoil if you argue against it. In my time developing
       | applications for front office at an investment bank, floating
       | point often works best.
       | 
       | Of course in your case though, for a billing system, the method
       | you describe is obviously the right one.
        
         | bxparks wrote:
         | You are getting a lot of down-votes, but you are correct, and I
         | gave you some upvotes, at least one.
         | 
         | If the application is doing financial modeling and estimations,
         | where only 1-3 decimal place of accuracy is needed, then
         | floating point is the right choice. It greatly simplifies the
         | app.
         | 
         | If the application is doing accounting, payments and billing,
         | where people expect accuracy to the penny or more (e.g. to
         | 1/10000 of a penny), then it needs to use a Decimal type.
        
         | mamcx wrote:
         | Floating point is bad as null are, and is defended by the same
         | apologist of null: "I don't make mistakes... so is good!".
         | 
         | Floating point ARE a major source of errors across everyone
         | that use them. ARE infectious. ARE semantically wrong. ARE not
         | made for financial calculation.
         | 
         | ARE WRONG.
         | 
         | Period. Just because under a lot of discipline (or luck, or
         | just "assume" is working but nobody have checked, or work
         | before but how knows if today?) not make it a good choice for
         | financial/money.
         | 
         | Is the same error when people think old String types can be
         | used in the unicode world, instead of have a proper type for
         | that.
         | 
         | Luck help a lot. But is not something to be proud about.
        
           | cameronh90 wrote:
           | Finance isn't just banking and accounting. A huge amount of
           | finance is modelling, simulations, signal generation, etc.
           | where being fast is often way more important than being
           | completely 100% accurate. In financial modelling, errors from
           | floating point are going to be insignificant compared to all
           | the other assumptions you make in your models.
           | 
           | I have worked in finance for my entire career, and everyone
           | uses floating point arithmetic for dealing with money on the
           | modelling side (sometimes $0.01 = 1.0, sometimes $1 = 1.0,
           | depends on the institution/currency/convention/context, but
           | we have to deal with fractional money anyway).
           | 
           | They do NOT use it on the accounting/back office side. That
           | would be a spectacularly bad idea. Those systems are designed
           | for accuracy to the penny.
        
           | bidirectional wrote:
           | Well no, the key difference between null and floating point
           | is that for all its flaws, floating point is _by far_ the
           | fastest way of doing non-integer numerical computation. Null
           | is just an ugly convenience hack of arguable merit, floats
           | are fundamental.
           | 
           | They're not a major source of error when you're implementing
           | a model which is already inexact to a far larger degree than
           | the problems caused by floats. Black-Scholes does not
           | perfectly price an option, your bootstrapped curve is not a
           | perfect predictor of market conditions in 28 years time.
           | These are the problems faced in front-office finance, the
           | error is already so far beyond 1 + 0.1 not perfectly matching
           | 1.1 that it's not worth caring about. I've worked on
           | applications where users just wanted to see numbers to the
           | nearest 100k so they could model out a few trades they
           | planned to make over the phone.
           | 
           | When you're working on a retail banking app where you need to
           | track customer's balances, or an accounting system, or
           | anything like that, then sure, floating point would be
           | malpractice. That is nothing like any of the applications
           | I've worked on in the financial field.
        
         | devwastaken wrote:
         | How did you handle the properties of floating point? The reason
         | people recoil at that more than likely has to do with lack of
         | knowledge in how floats are wrangled to ensure they're
         | accurate.
        
           | stevesimmons wrote:
           | Which properties?
           | 
           | For front-office risk and pricing calcs, speed of calculation
           | matters most. Hence IEEE754 float64.
           | 
           | Fixed precision decimals really only matter for middle and
           | back-office, for trade confirmation and settlement.
        
             | tantalor wrote:
             | What's the difference between front/middle/back office?
        
               | arthurcolle wrote:
               | In the context of a bulge bracket investment bank, it's
               | basically like this:
               | 
               | Front office - S&T (sales & trading), i.e. revenue
               | generating activity. Usually includes any quants/quant
               | developers actively working on things that make money
               | 
               | Middle office - operations. handles settlements,
               | confirms, and generally anything related to the post-
               | trade flow that is "after the trade is booked"
               | 
               | Back office - accounting, legal, engineering, IT support,
               | HR. Anything that isn't a revenue center that also isn't
               | even tangentially facing revenue generating operations
        
           | bidirectional wrote:
           | Which properties do you mean in particular? The main point is
           | just that finance doesn't necessarily require perfect
           | accuracy. It does when Bob sends Alice $1 and their account
           | balances must line up perfectly, it doesn't when you're
           | implementing models which already have greater error than
           | floating point could imbue. Not to mention that decimals,
           | integers and rationals cannot compute something as simple as
           | compound interest without lack of accuracy, so they're not
           | going to save you when you're implementing Black-Scholes.
        
             | lamp987 wrote:
             | >rationals cannot compute something as simple as compound
             | interest without lack of accuracy
             | 
             | Care to elaborate?
        
               | bidirectional wrote:
               | (Continiously) compound(ed) interest is e^(rate * time),
               | e is not a rational number. Transcendental functions are
               | commonly used in financial modelling, and once they
               | appear, nothing short of a full-blown CAS will give you
               | 100% accurate results (not that you should care, because
               | your model is off by more than floating point error).
        
             | gamache wrote:
             | > finance doesn't necessarily require perfect accuracy
             | 
             | Maybe finance doesn't, but billing does.
        
               | bidirectional wrote:
               | Yes, of course, I said that in my original comment. I'm
               | arguing the advice as a panacea, not saying the OP was
               | wrong to follow it.
        
         | smallnamespace wrote:
         | Yes, every time someone categorically declaims that 'floats and
         | money should never mix', I question whether they've ever met a
         | real accountant.
         | 
         | Accountants frequently spend all day in Excel. Excel uses
         | floats for all computations (doubles, to be precise) [1].
         | 
         | Now, in all fairness, an accountant and developer's
         | relationship to the numbers is rather different.
         | 
         | For an accountant, the risk of floats blowing up is largely
         | mitigated by the fact that they have a close, intimate
         | relationship with the actual numbers.
         | 
         | The responsible accountant should always deliver numbers they
         | have personally reviewed, while a developer is usually
         | automating a process, generating numbers that have yet to touch
         | a human eye, so there is rather less room for error.
         | 
         | Still, it's simply untrue that one should _never_ use floats
         | for money. Many of the cases where floats would generate bad
         | results are also problematic for simple alternatives. For
         | example, fixnums are simply  'floats that can't float', so you
         | need to be able to guarantee a fixed range ahead of time.
         | 
         | Understanding basic numerical analysis is unavoidable to
         | writing correct code.
         | 
         | [1]
         | https://en.wikipedia.org/wiki/Numeric_precision_in_Microsoft...
        
       ___________________________________________________________________
       (page generated 2021-04-05 23:01 UTC)