Remix.run Logo
kragen 2 days ago

This is an incredibly valuable article for anyone who's trying to make sense of decibels in some context. Michał clearly explains almost all of the gotchas you have to understand.

I realized recently, after years of doing it for signal powers, that dB are a pretty convenient way to do mental logarithmic estimates for things that have nothing to do with power or signals, with only a small amount of memorization. Logarithms are great because they allow you to do multiplication with just addition, and mental addition isn't that hard. For example, if you want to know how many pixels are in a 3840×2160 4K display, well, log₁₀(3840) ≈ 3.58 (35.8dB-pixel) and log₁₀(2160) ≈ 3.33 (33.3dB-pixel), and 3.58 + 3.33 = 6.91 (69.1 dB-square-pixel), and 10⁶·⁹¹ ≈ 8.13 million. The correct number is 8.29 million, so the result is off by about 2%, which is precise enough for many purposes. (To be fair, though, 4000 × 2000 = 8000, which is only off by 3.5%.)

The great difficulty with logarithms is that you need a table of logarithms to use them, and a mental table of logarithms is a lot of rote memorization. You can get pretty decent results linearly interpolating between entries in a table of logarithms, so you can use a lot more logarithms than you know, but you have to know some.

It's pretty commonplace in EE work to make casual use of the fact that a factor of 2× [in power] is about 3 dB, which is a surprisingly good approximation (3.0103dB is a more precise number). This is related to the hacker commonplace that 2¹⁰ = 1024 ≈ 1000 = 10³; 1024× is 30.103dB, while 1000× is precisely 30dB.

To the extent that you're willing to accept this approximation, it allows you to easily derive several other numbers. 4× is 6dB, 8× is 9dB, 16× is 12dB, and therefore 1.6× is 2dB. ½× is -3dB, so 5× is 7dB (10-3). So with just 2× = 3.01dB we already know the base-10 logarithms of 1, 2, 4, 5, and 8, to fairly good precision. That's half of the most basic logarithm table. (The most imprecise of these is 8: 10⁰·⁹ is about 7.94, which is an error of about -0.7% when the right answer was 8.)

If we're willing to add a second magic number to our memorization, 3× ≈ 4.77dB. This allows us to derive 6× ≈ 7.78dB and 9× ≈ 9.54dB. So, with two magic numbers, we have fairly precise logarithms for 1, 2, 3, 4, 5, 6, 8, and 9.

The only multiplier digit we're missing is 7. (Shades of the Pentium's ×3 circuit: http://www.righto.com/2025/03/pentium-multiplier-adder-rever....) So a third magic number to memorize is that 7× ≈ 8.45dB. And now we can mentally approximate products and quotients with mentally interpolated logarithms.

You can do my example above of 3840×2160 as follows. 3.8 is 80% of the way from 3 (4.8dB) to 4 (6.0dB), so it's about 5.8dB. 2.2 is 20% of the way from 2 (3.0dB) to 3 (4.8dB), so about 3.4dB. 35.8dB + 33.4dB = 69.2dB, which is between 8 million (69.0dB) and 9 million (69.5dB), about 40% of the way, so our linear interpolation gives us 8.4 million. This result is high by 1.2%, which is much better than you'd expect from the crudity of the estimation process.

For a more difficult problem, what's the diameter of a round cable with 1.5 square centimeters of cross-sectional area? That's 150mm², half of 300mm², so 24.77 dB-square-millimeters minus 3.01, 21.76dB. A = πr². Divide by π by subtracting 5dB (okay, I guess that's a fourth magic number: log₁₀(π) ≈ 4.97dB) and you're at 16.76dB. Take the square root to get the radius by dividing that by 2: 8.38dB-millimeters. That's less than 7× ≈ 8.45dB by only 0.07dB, so 7-millimeter radius is a pretty decent approximation, 14mm diameter. The precise answer is closer to 13.82mm.

For approximating small corrections like that, it can be useful to keep in mind that ln(10) ≈ 2.303 (a fifth magic number to memorize), so every 1% of a dB (10¹·⁰⁰¹) is a change of about 0.23%. So that leftover 0.07dB meant that 7mm was high by a couple percent.

More crudely: 150mm² is 22dB, ÷π is 17dB, √ is 8½ (pace Fellini), 7×.

It's pretty common in engineering and scientific calculations like this to have a lot of factors to multiply and divide, increasing the number of additions and subtractions relative to the number of logarithmic conversions; this is why slide rules were so popular. Maybe you derived the 1.5cm² number from copper's conductivity and a resistance bound, or from the yield strength of a steel and a load, say. 3840×2160 pixels × 4 bytes/pixel / (10.8 gigabytes/second), as I was calculating last night in https://news.ycombinator.com/item?id=44056923? That's just 35.8 dB + 33.3dB + 6dB - 100.3dB = -25.2dB-seconds, which is 3.0 milliseconds to memcpy that 4K framebuffer. (I didn't do that mentally, though.) Even 36 + 33 + 6 - 100 = -25, so π ms, is a fine approximation if what you want to know is mostly whether it's more or less than 16.7 ms.

So here's a full list of the seven magic numbers to memorize for these purposes:

  2× ≈ 3.01dB (∴ 4×, 8×, 5×)
  3× ≈ 4.77dB (∴ 6×, 9×, 1.5×)
  7× ≈ 8.45dB
  π× ≈ 4.97dB
  ln(10) ≈ 2.303 (∴ 0.01dB ≈ 0.23%, etc.)
  1.259× ≈ 1dB (+1dB ≈ +25.9%)
  (1 - .206)× ≈ -1dB (-1dB ≈ -20.6%)
I haven't been applying this approach long; I'll try to report on results later.
oddthink 13 hours ago | parent | next [-]

I've been using decibels as a scale for log-odds for a while when reporting results. It works pretty well, since the relevant part of the scale is wide, unlike using nepers, which I had never heard of until I started noodling around with this.

kragen 11 hours ago | parent [-]

Like, how many decibels of evidence does this observation provide for this hypothesis? That seems potentially pretty workable, as long as you can ensure conditional independence.

kragen 16 hours ago | parent | prev | next [-]

I wrote:

> So with just 2× = 3.01dB we already know (...) 8, to fairly good precision. (...) (The most imprecise of these is 8: 10⁰·⁹ is about 7.94, which is an error of about -0.7% when the right answer was 8.)

This is slightly mixed up. It's true that approximating 8× as 9dB gives you an 0.7% error. But I was talking about 3.01dB, and approximating 8× as 9.03dB gives 7.998×, only about 0.02% low.

The errors for the logarithms of the 10 digits thus approximated are:

  >>> print('\n'.join([f'  {10*p:.2f}: {100*(10**p-i-1)/(i+1):+.3f}%' for i, p in enumerate([0, .301, .477, .602, .699, .778, .845, .903, .954])]))
  0.00: +0.000%
  3.01: -0.007%
  4.77: -0.028%
  6.02: -0.014%
  6.99: +0.007%
  7.78: -0.035%
  8.45: -0.023%
  9.03: -0.021%
  9.54: -0.056%
hatthew 7 hours ago | parent | prev [-]

Does this have anything to do with decibels specifically or is it just general log-space arithmetic?

kragen 6 hours ago | parent [-]

Decibels specifically are just general log-space arithmetic. (Usually.)