News: 1620386649

  ARM Give a man a fire and he's warm for a day, but set fire to him and he's warm for the rest of his life (Terry Pratchett, Jingo)

How Berkshire Hathaway broke Nasdaq's 32-bit code with its monster share price

(2021/05/07)


Bug of the week Here's a programming gremlin that caught our eye this week: a share price exceeded the 32-bit unsigned integer limit of a stock exchange's code.

Berkshire Hathaway is an investment group known not just for being run by billionaire tycoon Warren Buffett, but also because its BRK.A stock is ridiculously priced: at time of writing, $435,120.00 (£312,818.65) apiece. It is listed on the New York Stock Exchange, which is unaffected by the following bug.

On Tuesday, the Nasdaq exchange [1]ceased transmitting information about the stock on its website and in feeds to brokers and other financial organizations. The webpage for the stock simply says: "Data is currently not available."

[2]

[3]

[4]

That's because the BRK.A value exceeded the maximum value that at least some parts of Nasdaq's software can safely handle.

And this is all because it turns out Nasdaq uses 32-bit unsigned integers to record and send quotes for shares. The maximum value of such a 32-bit variable is 2 32 - 1, or 0xffffffff in hexadecimal, or 4,294,967,295 in decimal.

Nasdaq chose not to store prices using a floating-point number format normally encountered in applications, probably because they can be [5]approximate , and instead chose to multiply quotes by 10,000 and store them as 32-bit unsigned integers. For example, the value 123,456 would represent a stock price of $12.3456, precise down to the hundredth of a penny. The value 7,890,000 would represent a stock price of $789.0000.

[6]

And so BRK.A's $435,120.0000 price would be stored as 4,351,200,000, which exceeds the 4,294,967,295 maximum, and would overflow to some value far lower than the actual stock price. In effect, the value would wrap around from the maximum to zero, and in fact go past zero to [7]56,232,704 , or $5,623.2704.

If the faulty price was broadcast to the world by Nasdaq, there would be bedlam. Imagine thinking you could snap up Berkshire Hathaway shares for less than $6,000 apiece, or that your holdings of the stock were suddenly ruined?

[8]BadAlloc: Microsoft looked at memory allocation code in tons of devices and found this one common security flaw

[9]Keen to go _ExtInt? LLVM Clang compiler adds support for custom width integers

[10]Need 32-bit Linux to run past 2038? When version 5.6 of the kernel pops, you're in for a treat

[11]Sudo? More like Su-doh: There's a fun bug that gives restricted sudoers root access (if your config is non-standard)

Nasdaq said it will update its software to correct the issue by May 17, and stopped BRK.A's data going out before it oveflowed. A solution would be to use 64-bit unsigned integers, giving you the ability to handle a maximum value of 18,446,744,073,709,551,615, or a share price of $1,844,674,407,370,955.1615. That's plenty of breathing room, for now.

The 90-year-old Buffett won't budge on splitting his group's class A stock, which for what it's worth, is why it's so much higher than anything else on the market.

Meanwhile, the IEX Exchange [12]stopped accepting orders for BRK.A in mid-March "due to an internal price limitation within the trading system. Any orders sent in this symbol will be rejected until further notice." To us, that sounds like it suffered the same problem as Nasdaq.

[13]

Aptly, BRK is a 6502 CPU assembly code mnemonic for a breakpoint, which can be used to troubleshoot a program that's gone wrong. ®

Hat tip to the Wall Street Journal for [14]highlighting this flaw earlier this week.

Get our [15]Tech Resources



[1] https://www.nasdaq.com/market-activity/stocks/brk-a

[2] https://pubads.g.doubleclick.net/gampad/jump?co=1&iu=/6978/reg_software/applications&sz=300x50%7C300x100%7C300x250%7C300x251%7C300x252%7C300x600%7C300x601&tile=2&c=2YJVkGgcti2U4K6JnSM6M9gAAAEo&t=ct%3Dns%26unitnum%3D2%26raptor%3Dcondor%26pos%3Dtop%26test%3D0

[3] https://pubads.g.doubleclick.net/gampad/jump?co=1&iu=/6978/reg_software/applications&sz=300x50%7C300x100%7C300x250%7C300x251%7C300x252%7C300x600%7C300x601&tile=4&c=44YJVkGgcti2U4K6JnSM6M9gAAAEo&t=ct%3Dns%26unitnum%3D4%26raptor%3Dfalcon%26pos%3Dmid%26test%3D0

[4] https://pubads.g.doubleclick.net/gampad/jump?co=1&iu=/6978/reg_software/applications&sz=300x50%7C300x100%7C300x250%7C300x251%7C300x252%7C300x600%7C300x601&tile=3&c=33YJVkGgcti2U4K6JnSM6M9gAAAEo&t=ct%3Dns%26unitnum%3D3%26raptor%3Deagle%26pos%3Dmid%26test%3D0

[5] https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

[6] https://pubads.g.doubleclick.net/gampad/jump?co=1&iu=/6978/reg_software/applications&sz=300x50%7C300x100%7C300x250%7C300x251%7C300x252%7C300x600%7C300x601&tile=4&c=44YJVkGgcti2U4K6JnSM6M9gAAAEo&t=ct%3Dns%26unitnum%3D4%26raptor%3Dfalcon%26pos%3Dmid%26test%3D0

[7] https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=10ecf0c76aa824fb5876b3feed641389

[8] http://www.theregister.com/2021/04/29/microsoft_badalloc_iot/

[9] http://www.theregister.com/2020/04/24/llvm_project_adds_support_for/

[10] http://www.theregister.com/2020/01/30/linux_5_6_2038/

[11] http://www.theregister.com/2019/10/14/linux_sudo_security_bug/

[12] https://iextrading.com/alerts/#/143

[13] https://pubads.g.doubleclick.net/gampad/jump?co=1&iu=/6978/reg_software/applications&sz=300x50%7C300x100%7C300x250%7C300x251%7C300x252%7C300x600%7C300x601&tile=3&c=33YJVkGgcti2U4K6JnSM6M9gAAAEo&t=ct%3Dns%26unitnum%3D3%26raptor%3Deagle%26pos%3Dmid%26test%3D0

[14] https://www.wsj.com/articles/berkshire-hathaways-stock-price-is-too-much-for-computers-11620168548

[15] https://whitepapers.theregister.com/

+1 for the Headline and all to funny tag line!

chivo243

Glad I wasn't drinking tea... Buffet overflow!

Use of floating point numbers ?

alain williams

Storing financial quantities in floating point will only give you a head ache; eg do not store a bank balance in pounds. Store it as an integer number of pennies (or whatever the smallest currency unit is). If you store in floating point you might get a rounding error of a penny and the auditors will go bananas looking for someone [1]bacon or salami slicing .

Having said that: I do see people manipulating prices in Javascript where numbers are stored as double floating point (IEEE754); but the maximum integer value that can be safely held is 9,007,199,254,740,992 ~= 9×10 15 - which can easily hold a BRK.A.

You might need to do some calculations in 1/100 of pennies - to keep the VAT people happy.

[1] https://en.wikipedia.org/wiki/Salami_slicing

Re: Use of floating point numbers ?

Yet Another Anonymous coward

But then you have to explain to auditors why 1/3 + 1!3 + 1/3 doesn't add to 1.

While they are being paid $10,000/day not to believe you

Re: Use of floating point numbers ?

Brewster's Angle Grinder

Maybe electronic trading allows fractions of a penny or a cent. But you can't get 1/3 of a penny out of a cash till. Sooner or later you have to make a decision about how to round to integer currency units - be it one penny of 2.220446049250313e-16 of a penny.

And while 1/3 + 1/3 + 1/3 happens to work 1/6+ 1/6 + 1/6 + 1/6 + 1/6 + 1/6 != 1.0 Should you truly need to work with rationals, use a class that implements them.

"you have to make a decision about how to round to integer currency units"

LDS

Usually these decisions are already made for you - there are specific rules you have to abide to.

Re: Use of floating point numbers ?

Anonymous Coward

I thought (having seen Superman 3) that the result of 1/3 + 1/3 +1/3 not adding to 1 meant the conversation that needed to be had with auditors was how you afforded the Ferrari outside on your salary

12.1 - 12 - 0.1 != 0

Brewster's Angle Grinder

Nasdaq chose not to store prices using a floating-point number format normally encountered in applications...and instead chose to multiply quotes by 10,000 and store them as 32-bit unsigned integers.

The advice from lawyers tends to be don't use a lawyer unless you absolutely have no choice. As someone who works with floats, my answer is the same. You could store an integer in a float; that would give you 53 bits. (1 implied, and 52 bits of data.) But why bother if it fits in a 32 bit int?

Strahd Ivarius

if we had kept good old COBOL for anything related to money, this wouldn't have been an issue!

Anonymous Coward

Really! Bloomberg terminals would be about a week behind by now....

Anonymous Coward

Very dim and distant memories seem to tell me that Data General Basic supported a much larger number range than if you used string variables instead of normal ones .... and things like

LET A$ = B$ + "1"

worked.

Good news

Flocke Kroes

Years ago IBM spotted that using binary floating point when scaled integers are required caused problems. They came up with a way of storing numbers internally in decimal instead of binary. You can quickly try it out by firing up python3 and typing:

from decimal import Decimal

Decimal(2) / Decimal(7) == Decimal(1) / Decimal(7) * Decimal(2)

2 / 7 == 1 / 7 * 2 And you get the result False for Decimal and True for binary floating point. It is almost as if using Decimal when you need integers is just as broken as using binary floating point when you need integers. All that work implementing decimal arithmetic and it still does not solve the problem of programmers using floating point where scaled integers are required.

(In python3 int / int -> float. If you want C flavoured division, use the // operator.)

You nearly got me there

Pigeon

1 / 7 is not a fair test, since it is an irrational number. I would not be so quick to dismiss python on this basis. 1/10 is a more realistic test.

I think perl6 does some floating point nearly-equally thing with floating point. It calls them Rats. Cobol is probably ok if you put the full stop in after the definition section.

Re: Good news

Anonymous Coward

Wasn't that why the IEEE 854 standard was derived from 754 - floating point formats for non-binary radices (though seems it got folded back into 754 in 2008 with 754 suppoting binary and decimal radices)

rdhma

One solution would be for Nasdaq to require a stock split once the price exceeds $largenumber.

Buffet doesn't like stock splits, believing that they encourage short-term dabbling in the market, while he is a long-term investor.

Neil Barnes

He's older than my late father... he may be leaving it a bit late to take his profits!

captain veg

Way back when, Microsoft released version 3.11 of Windows, also known as Windows for Warehouses because it brought no new features for anyone not connected to a networks, which was most people at the time. There was much merriment that the Windows Calculator app asserted that 3.11 - 3.1 = 0. This wasn't fixed, IIRC, until Windows 98.

-A.

What planet?

Mike 137

" A solution would be to use 64-bit unsigned integers "

There are other solutions too, including quite a choice of arbitrary precision math libraries out there - (a simple example is Java's BigDecimal) - that don't suffer from the inaccuracies of conventional IEEE floating point. This ain't a hard nut to crack.

This has happened with them before

kmceject

Working at a Market Data Provider in the 80s and 90s we used all sorts of compression and limitations to keep our data feed fast, since we were sending ticker info out at the warp speed of 38.4kb async. (Inputs from the exchanges were a maximum of 19.2kb and we had about 15 different exchanges at the time as I recall.) The limit for a price dollar was 2 bytes but one bit was reserved so we had a price limit of $32768. Our stream used lots of bit masking where certain bits were used for various details. The encoding allowed us to take an 80 byte message from the exchange to put out the same data in about 14 bytes.)

One day the developers of that code started to panic when they realized that Berkshire Hathaway was reaching that limit. They had to spend days trying to figure how to change the code to allow for a different bit to be used for that flag bit and how to get that code out to the customers so they could read the new encoding. We didn't make it for all the customers because it required mailing a disk to them with the new software.

AndrueC

Floating point calculations in programs are a horror just waiting to trip you up when you least expect it. It's rather ironic that computers are actually pretty bad(*) at performing floating point calculations. The one thing everyone expects them to do and they are bad at it...

(*)There are of course ways to mitigate the problem but you have to choose to use them. I suspect most programmers don't even know there's a problem. They think that [1]1/10 is easy to calculate :)

[1] https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/

Spoobistle

Well, floating point representations were designed to allow scientists and engineers to use widely ranging quantities without having to think about scaling in each expression. Remember, at that time the alternatives to the (digital) computer doing it were the human computer with a slide rule or log tables! Or of course electronic or mechanical analog computers.

John G Imrie

What ever happened to binary coded decimals?

The Latest Get-Rich-Quick Scheme: Bashing Linux

As used by Jesse Berst and Fred Moody...

1. Write a scathing article attacking some facet of Linux and publish it
2. Arrange for the article to be mentioned on LinuxToday or Slashdot.
3. Watch as thousands of angry Linux zealots storm your article and load
the advertising banners. Listen to the ca-chink $ound of the
advertising revenue that's pouring in.
4. As soon as the maelstrom quiets, publish another scathing article about
the immaturity of the Linux "community", excerpting some of the nasty
flames from Linux longhairs denouncing your intelligence and claiming
that you're on the Microsoft payroll.
5. Arrange for the article to be mentioned on LinuxToday or Slashdot.
6. Watch as thousands of angry Linux zealots storm your article...
7. Wait for a few weeks, and repeat. Cash your inflated paycheck, invest
the proceeds in some Linux stocks, and retire early. You've "earned" it!