<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="http://h14s.p5r.org/feed" rel="self" type="application/atom+xml" /><link href="http://h14s.p5r.org/" rel="alternate" type="text/html" /><updated>2024-12-06T10:10:53+01:00</updated><id>http://h14s.p5r.org/feed</id><title type="html">Hummus and Magnets</title><subtitle>I’m Christian Plesner Hansen. I’m a software engineer working out of Århus, Denmark. This is my technical blog.</subtitle><author><name>{&quot;name&quot;=&gt;&quot;&quot;, &quot;email&quot;=&gt;&quot;&quot;}</name><email></email></author><entry><title type="html">Varfloats</title><link href="http://h14s.p5r.org/2024/12/06/varfloats.html" rel="alternate" type="text/html" title="Varfloats" /><published>2024-12-06T10:00:00+01:00</published><updated>2024-12-06T10:00:00+01:00</updated><id>http://h14s.p5r.org/2024/12/06/varfloats</id><content type="html" xml:base="http://h14s.p5r.org/2024/12/06/varfloats.html"><![CDATA[<style>
  .cont { color: #b00000 }
  .sign { color: #ff9900 }
  .expn { color: #008000 }
  .mant { color: #000080 }
</style>

<p>My <a href="/2024/11/11/bigger-better-varints.html">last post</a> was about a varint format that can hold values from 7 to 2048 bits, LPV256. Here is the format in a nutshell,</p>

<p class="codeblock">
   7 bits: <span class="cont">0</span>xxxxxxx<br />
  14 bits: <span class="cont">10</span>xxxxxx xxxxxxxx<br />
  21 bits: <span class="cont">110</span>xxxxx xxxxxxxx xxxxxxxx<br />
  28 bits: <span class="cont">1110</span>xxxx xxxxxxxx xxxxxxxx xxxxxxxx<br />
  35 bits: <span class="cont">11110</span>xxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx <br />
  64 bits: <span class="cont">11111000</span> + 8 b<br />
 128 bits: <span class="cont">11111001</span> + 16 b<br />
 256 bits: <span class="cont">11111010</span> + 32 b<br />
 512 bits: <span class="cont">11111011</span> + 64 b<br />
1024 bits: <span class="cont">11111100</span> + 128 b<br />
2048 bits: <span class="cont">11111101</span> + 256 b<br />
   unused: <span class="cont">1111111</span>x
</p>

<p>An alternative view of the format though is that it can be a container for any data of variable size. It doesn’t have to just hold integers. For instance, a different thing you might want to store in a variable-size format are floating-point values.</p>

<p>Floating-point values are trickier to store with variable size. With integers it’s common that values happen to be small and you will often be able to automatically get some benefit from a variable-size integer encoding. With floating-point values though you will rarely get small values by accident, whatever your definition of “small” is. If you’re doing a single or double precision computation you’re likely to end up with a value that requires full single or double precision to represent.</p>

<p>Even a constant like <code class="language-plaintext highlighter-rouge">0.1d</code> that looks small or simple isn’t. The real value isn’t the mathematical value <em>0.1</em> but the closest double-precision approximation, in this case <code class="language-plaintext highlighter-rouge">0.100000000000000006</code>. That’s tricky to store with a smaller representation than the full 64 bits. There are values that both look and are small, like <code class="language-plaintext highlighter-rouge">0.0</code>, <code class="language-plaintext highlighter-rouge">0.5</code>, and the integers. But you’re less likely to run into those by accident.</p>

<p>For this reason the benefit of varfloats is different from that of varints. You’re unlikely to automatically save space. If you want a <code class="language-plaintext highlighter-rouge">0.1</code> that doesn’t take up much space you have to explicitly discard precision to make it small. You might use single precision <code class="language-plaintext highlighter-rouge">0.1f</code> instead of double precision <code class="language-plaintext highlighter-rouge">0.1d</code>. That gives you a different approximation, one that fits into 32 bits, in this case <code class="language-plaintext highlighter-rouge">0.10000000149</code>. Or you might go even lower, to half or 8-bit precision. In this case the benefit of varfloats is that if you explicitly ensure that your value fits in a smaller representation then the encoding will detect that and use less space. You don’t have to explicitly specify what size you want, or have all floats take up 32 or 64 bits. It saves your data format from having to make awkward tradeoffs or assumptions about how to store floats.</p>

<p>This also says something about what kinds of values should be small. It should be those you get from discarding precision. IEEE-754 defines some precisions down to 16 bits and there are 8-bit precision values in practical use<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>.</p>

<p class="codeblock">
minifloat (8): <span class="sign">s</span><span class="expn">eeee</span><span class="mant">mmm</span> <br />
half (16):     <span class="sign">s</span><span class="expn">eeeee</span><span class="mant">mm mmmmmmmm</span> <br />
single (32):   <span class="sign">s</span><span class="expn">eeeeeee e</span><span class="mant">mmmmmmm mmmmmmmm mmmmmmmm</span> <br />
double (64):   <span class="sign">s</span><span class="expn">eeeeeee eeee</span><span class="mant">mmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm</span>
</p>

<p>These are the formats people are likely to produce so those are the ones we’d like to be able to store in less space. Since LPV256 has fixed size buckets we can’t just fit in those sizes though. There is no 8- or 16-bit encoding. only 7, 14, 21 bits and so on. So some tweaking is required. But at a minimum it should be the case that.</p>

<ul>
  <li>The 7-bit encoding should hold values from minifloat.</li>
  <li>Minifloat values that don’t fit within 7 bits should fit in 14.</li>
  <li>The 14-bit encoding should hold half precision values.</li>
  <li>Half precision values that don’t fit within 14 bits should fit in 21.</li>
  <li>… and so on up to 32 and 64 bit values.</li>
</ul>

<h3 id="the-construction">The construction</h3>

<p>One approach would be to use the fact that while IEEE-754 only defines a few precisions, you can define precisions of any size. You can define as small as a 4-bit float if you want and, more to the point, a 7-, 14-, or 21-bit format. You just have to decide how many of the bits go to the exponent and mantissa. Here is one way to define them:</p>

<p class="codeblock">
   7 bits: <span class="sign">s</span><span class="expn">eee</span><span class="mant">mmm</span><br />
  14 bits: <span class="sign">s</span><span class="expn">eeee</span><span class="mant">mm mmmmmmm</span><br />
  21 bits: <span class="sign">s</span><span class="expn">eeeee</span><span class="mant">m mmmmmmm mmmmmmm</span><br />
  28 bits: <span class="sign">s</span><span class="expn">eeeeee e</span><span class="mant">mmmmmm mmmmmmm mmmmmmm</span><br />
  32 bits: <span class="sign">s</span><span class="expn">eeeeeee e</span><span class="mant">mmmmmmm mmmmmmmm mmmmmmmm</span><br />
  64 bits: <span class="sign">s</span><span class="expn">eeeeeee eeee</span><span class="mant">mmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm</span>
</p>

<p>This way you can define a varfloat format like this.</p>

<ol>
  <li>Take your input, say a double precision value.</li>
  <li>Convert it to a 7-bit float. Compare the result to the original input. If they represent the same value then that is the result.</li>
  <li>Otherwise, convert it to a 14-bit float. If the result represents the same value as the input that is your result.</li>
  <li>…and so on for 21, 28, and 32 bits.</li>
  <li>If none of the previous steps have succeeded the input requires full 64 bits.</li>
</ol>

<p>Converting between different precisions is a well-defined operation (well, not quite but we’ll get to NaNs in a moment) so this encoding is well-defined too. However, it’s not obvious that it can be done efficiently. And there are devils in the details. But just to get a sense for how this works in practice here is a table of all the values that will fit in a single varfloat byte,</p>

<table>
  <thead>
    <tr>
      <th>sign</th>
      <th>exp</th>
      <th><code class="language-plaintext highlighter-rouge">000</code></th>
      <th><code class="language-plaintext highlighter-rouge">001</code></th>
      <th><code class="language-plaintext highlighter-rouge">010</code></th>
      <th><code class="language-plaintext highlighter-rouge">011</code></th>
      <th><code class="language-plaintext highlighter-rouge">100</code></th>
      <th><code class="language-plaintext highlighter-rouge">101</code></th>
      <th><code class="language-plaintext highlighter-rouge">110</code></th>
      <th><code class="language-plaintext highlighter-rouge">111</code></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0</code></td>
      <td><code class="language-plaintext highlighter-rouge">000</code></td>
      <td>0</td>
      <td><em>0.03125</em></td>
      <td><em>0.0625</em></td>
      <td><em>0.09375</em></td>
      <td><em>0.125</em></td>
      <td><em>0.15625</em></td>
      <td><em>0.1875</em></td>
      <td><em>0.21875</em></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0</code></td>
      <td><code class="language-plaintext highlighter-rouge">001</code></td>
      <td>0.25</td>
      <td>0.28125</td>
      <td>0.3125</td>
      <td>0.34375</td>
      <td>0.375</td>
      <td>0.40625</td>
      <td>0.4375</td>
      <td>0.46875</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0</code></td>
      <td><code class="language-plaintext highlighter-rouge">010</code></td>
      <td>0.5</td>
      <td>0.5625</td>
      <td>0.625</td>
      <td>0.6875</td>
      <td>0.75</td>
      <td>0.8125</td>
      <td>0.875</td>
      <td>0.9375</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0</code></td>
      <td><code class="language-plaintext highlighter-rouge">011</code></td>
      <td>1</td>
      <td>1.125</td>
      <td>1.25</td>
      <td>1.375</td>
      <td>1.5</td>
      <td>1.625</td>
      <td>1.75</td>
      <td>1.875</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0</code></td>
      <td><code class="language-plaintext highlighter-rouge">100</code></td>
      <td>2</td>
      <td>2.25</td>
      <td>2.5</td>
      <td>2.75</td>
      <td>3 3.25</td>
      <td>3.5</td>
      <td>3.75</td>
      <td> </td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0</code></td>
      <td><code class="language-plaintext highlighter-rouge">101</code></td>
      <td>4</td>
      <td>4.5</td>
      <td>5</td>
      <td>5.5</td>
      <td>6</td>
      <td>6.5</td>
      <td>7</td>
      <td>7.5</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0</code></td>
      <td><code class="language-plaintext highlighter-rouge">110</code></td>
      <td>8</td>
      <td>9</td>
      <td>10</td>
      <td>11</td>
      <td>12</td>
      <td>13</td>
      <td>14</td>
      <td>15</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0</code></td>
      <td><code class="language-plaintext highlighter-rouge">111</code></td>
      <td>∞</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">1</code></td>
      <td><code class="language-plaintext highlighter-rouge">000</code></td>
      <td>-0</td>
      <td><em>-0.03125</em></td>
      <td><em>-0.0625</em></td>
      <td><em>-0.09375</em></td>
      <td><em>-0.125</em></td>
      <td><em>-0.15625</em></td>
      <td><em>-0.1875</em></td>
      <td><em>-0.21875</em></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">1</code></td>
      <td><code class="language-plaintext highlighter-rouge">001</code></td>
      <td>-0.25</td>
      <td>-0.28125</td>
      <td>-0.3125</td>
      <td>-0.34375</td>
      <td>-0.375</td>
      <td>-0.40625</td>
      <td>-0.4375</td>
      <td>-0.46875</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">1</code></td>
      <td><code class="language-plaintext highlighter-rouge">010</code></td>
      <td>-0.5</td>
      <td>-0.5625</td>
      <td>-0.625</td>
      <td>-0.6875</td>
      <td>-0.75</td>
      <td>-0.8125</td>
      <td>-0.875</td>
      <td>-0.9375</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">1</code></td>
      <td><code class="language-plaintext highlighter-rouge">011</code></td>
      <td>-1</td>
      <td>-1.125</td>
      <td>-1.25</td>
      <td>-1.375</td>
      <td>-1.5</td>
      <td>-1.625</td>
      <td>-1.75</td>
      <td>-1.875</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">1</code></td>
      <td><code class="language-plaintext highlighter-rouge">100</code></td>
      <td>-2</td>
      <td>-2.25</td>
      <td>-2.5</td>
      <td>-2.75</td>
      <td>-3</td>
      <td>-3.25</td>
      <td>-3.5</td>
      <td>-3.75</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">1</code></td>
      <td><code class="language-plaintext highlighter-rouge">101</code></td>
      <td>-4</td>
      <td>-4.5</td>
      <td>-5</td>
      <td>-5.5</td>
      <td>-6</td>
      <td>-6.5</td>
      <td>-7</td>
      <td>-7.5</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">1</code></td>
      <td><code class="language-plaintext highlighter-rouge">110</code></td>
      <td>-8</td>
      <td>-9</td>
      <td>-10</td>
      <td>-11</td>
      <td>-12</td>
      <td>-13</td>
      <td>-14</td>
      <td>-15</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">1</code></td>
      <td><code class="language-plaintext highlighter-rouge">111</code></td>
      <td>-∞</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
  </tbody>
</table>

<p>It’s not a huge set and not one you’re likely to hit by accident. But it does include common values like <code class="language-plaintext highlighter-rouge">0</code>, <code class="language-plaintext highlighter-rouge">1</code>, <code class="language-plaintext highlighter-rouge">-1</code>, <code class="language-plaintext highlighter-rouge">0.5</code>, ∞, -∞, etc. If you were going to pick a set of values that definitely should fit within the smallest varfloat I think it has a lot of them.</p>

<h3 id="conversion">Conversion</h3>

<p>Of course this only makes sense if we can do the conversion efficiently, and we can. To get a sense for how, consider what a single precision number looks like that can be stored as a 7-bit float:</p>

<table>
  <thead>
    <tr>
      <th>v</th>
      <th>7 bit</th>
      <th>32 bit</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td><code class="language-plaintext highlighter-rouge">0 000 000</code></td>
      <td><code class="language-plaintext highlighter-rouge">0 00000000 00000000000000000000000</code></td>
    </tr>
    <tr>
      <td>0.25</td>
      <td><code class="language-plaintext highlighter-rouge">0 001 000</code></td>
      <td><code class="language-plaintext highlighter-rouge">0 01111101 00000000000000000000000</code></td>
    </tr>
    <tr>
      <td>0.5</td>
      <td><code class="language-plaintext highlighter-rouge">0 010 000</code></td>
      <td><code class="language-plaintext highlighter-rouge">0 01111110 00000000000000000000000</code></td>
    </tr>
    <tr>
      <td>1</td>
      <td><code class="language-plaintext highlighter-rouge">0 011 000</code></td>
      <td><code class="language-plaintext highlighter-rouge">0 01111111 00000000000000000000000</code></td>
    </tr>
    <tr>
      <td>2</td>
      <td><code class="language-plaintext highlighter-rouge">0 100 000</code></td>
      <td><code class="language-plaintext highlighter-rouge">0 10000000 00000000000000000000000</code></td>
    </tr>
    <tr>
      <td>4</td>
      <td><code class="language-plaintext highlighter-rouge">0 101 000</code></td>
      <td><code class="language-plaintext highlighter-rouge">0 10000001 00000000000000000000000</code></td>
    </tr>
    <tr>
      <td>8</td>
      <td><code class="language-plaintext highlighter-rouge">0 110 000</code></td>
      <td><code class="language-plaintext highlighter-rouge">0 10000010 00000000000000000000000</code></td>
    </tr>
    <tr>
      <td>∞</td>
      <td><code class="language-plaintext highlighter-rouge">0 111 000</code></td>
      <td><code class="language-plaintext highlighter-rouge">0 11111111 00000000000000000000000</code></td>
    </tr>
  </tbody>
</table>

<p>We’re going to treat <code class="language-plaintext highlighter-rouge">0</code> and ∞ specially so the pattern that identifies single precision values is that they have either of these two forms:</p>

<p class="codeblock">
<span class="sign">s</span><span class="expn">011111ee</span><span class="mant">mmm00000000000000000000</span><br />
<span class="sign">s</span><span class="expn">100000ee</span><span class="mant">mmm00000000000000000000</span><br />
</p>

<p>Similarly, 32-bit floats that can be stored in 14 bits have either of these two forms,</p>

<p class="codeblock">
<span class="sign">s</span><span class="expn">01111eee</span><span class="mant">mmmmmmmmm00000000000000</span><br />
<span class="sign">s</span><span class="expn">10000eee</span><span class="mant">mmmmmmmmm00000000000000</span><br />
</p>

<p>And so on. For each size there is a particular set of exponents that will fit, and then a particular size of mantissa. There are only 256 possible exponents so we can simply make a table from those to the smallest format that will hold that exponent. Similarly we can count the number of leading zeroes in the mantissa and map that to the smallest format that will hold that mantissa. The max of those two values will be the smallest format that will hold the value.</p>

<p>Let’s take an example. Say we’re given this 32-bit float (which represents <code class="language-plaintext highlighter-rouge">3.1415405</code>),</p>

<p class="codeblock">
<span class="sign">0</span><span class="expn">10000000</span><span class="mant">10010010000111100000000</span>
</p>

<p>First we take the exponent, <code class="language-plaintext highlighter-rouge">10000000</code> (or 128), and look it up in the exponent-to-format table. That will tell us that a 7-bit varfloat can hold values with that exponent. Then we take the mantissa, <code class="language-plaintext highlighter-rouge">10010010000111100000000</code> and count how many bits are set: 15. We look that up in the mantissa-bits-to-format table which tells us that it requires a 21-bit varfloat. The widest format required is 21 bits so that’s what we’ll use. The result is</p>

<p class="codeblock">
<span class="sign">0</span><span class="expn">10000</span><span class="mant">100100100001111</span>
</p>

<p>The encoding step itself is just discarding the middle bits of the exponent (which are all the same and the negation of the top bit) as well as the bottom bits of the mantissa (which are all <code class="language-plaintext highlighter-rouge">0</code>). You’ll notice that the entire process only has one branch at the end, when we dispatch on the computed format (you can make the max branchless).</p>

<p>To decode the value we extend the exponent immediately below the top bit with the negation of the top bit. And we extend the mantissa with least significant <code class="language-plaintext highlighter-rouge">0</code> bits,</p>

<p class="codeblock">
<span class="sign">0</span><span class="expn">1<u>000</u>0000</span><span class="mant">100100100001111<u>00000000</u></span>
</p>

<p>The underlined bits are the one added. Similarly, decoding <code class="language-plaintext highlighter-rouge">0.5</code> from a 7-bit value (<code class="language-plaintext highlighter-rouge">0 010 000</code>) to 32 bits gives you</p>

<p class="codeblock">
<span class="sign">0</span><span class="expn">0<u>11111</u>10</span><span class="mant">000<u>00000000000000000000</u></span>
</p>

<p>This works on single precision values but earlier I talked about the input being double precision? That’s because I assume a first step where we recognize double precision values that fit within single precision and also recognize the exponent for <code class="language-plaintext highlighter-rouge">0.0</code> and treat it specially. So it’s not like this encoding is free, there’s a bit of branching and nontrivial work, but not all that much.</p>

<p>Why do we need to treat <code class="language-plaintext highlighter-rouge">0.0</code> differently? That’s because of denormals. The pattern we use above where we can just look at the exponent and mantissa separately doesn’t work for an exponent that’s all zero. There we need 7 bits for one particular value, <code class="language-plaintext highlighter-rouge">0.0</code> itself, when the mantissa is also all zero. And for nonzero values of the mantissa we need a full 64 bits because those are denormals and they won’t fit with less precision.</p>

<p>This also means that what I’ve described here doesn’t produce encoded denormals. I include denormal values like <code class="language-plaintext highlighter-rouge">0.125</code> in the table of 7-bit values above but if you run the encoding process as I’ve described it here they won’t actually be stored like that. Instead they’ll end up as 14-bit normal values. That’s why those values are in italic in the table. You can add an extra step to the 14-bit encoding to recognize values that will actually fit as 7-bit denormals (and similarly for 21-bit and so on) but it’s not necessary for correctness so I’ll leave that to the reader.</p>

<h3 id="nans">NaNs</h3>

<p>One more detail is NaNs. It’s not commonly used but each NaN value has a payload value stored in the mantissa. The problem there is that while it’s well-defined how you convert infinities, normals, and denormals to a different precision the IEEE-754 spec says nothing about how to convert NaNs. I’ve looked at how different languages and libraries specify floating point conversion and haven’t found any that mention it. Finally I’ve looked at processor instruction sets and it turns out that in practice NaNs are narrowed the same way other values are: you discard the least significant bits. So this 7-bit NaN, <code class="language-plaintext highlighter-rouge">0 111 110</code>, becomes this single-precision value: <code class="language-plaintext highlighter-rouge">0 11111111 11000000000000000000000</code>. That means that when encoding you can use exactly the same path for infinity and NaN as for other non-zero values which is nice. They do require special handling when decoding since you need to do sign extension slightly differently.</p>

<h3 id="endianness">Endianness</h3>

<p>The last thing to consider is: when some of the value is stored in the prefix, which part of the value to store? For a 14-bit value for instance, do we store the most significant bits in the prefix:</p>

<p class="codeblock">
<span class="cont">10</span><span class="sign">s</span><span class="expn">eeee</span><span class="mant">m mmmmmmmm</span>
</p>

<p>or the least significant,</p>

<p class="codeblock">
<span class="cont">10</span><span class="mant">mmmmmm</span> <span class="sign">s</span><span class="expn">eeee</span><span class="mant">mmm</span>
</p>

<p>I think it makes sense to store the least significant bits. If you look at the second byte in the second case, <span class="codeblock"><span class="sign">s</span><span class="expn">eeee</span><span class="mant">mmm</span></span>, that is just a minifloat. So you get a fast case when the prefix is <span class="cont">10</span><span class="mant">000000</span> where you can just read a minifloat directly from the second byte. This also simplifies writing values that you know are minifloats. The same works for the other precisions as well:</p>

<p class="codeblock">
   7 bits: <span class="cont">0</span><span class="sign">s</span><span class="expn">eee</span><span class="mant">mmm</span><br />
  14 bits: <span class="cont">10</span><span class="mant">mmmmmm</span> <span class="sign">s</span><span class="expn">eeee</span><span class="mant">mmm</span><br />
  21 bits: <span class="cont">110</span><span class="mant">mmmmm</span> <span class="sign">s</span><span class="expn">eeeee</span><span class="mant">mm mmmmmmmm</span><br />
  28 bits: <span class="cont">1110</span><span class="mant">mmmm</span> <span class="sign">s</span><span class="expn">eeeeeee</span> <span class="mant">mmmmmmmm mmmmmmmm</span><br />
  35 bits: <span class="cont">11110</span><span class="mant">mmm</span> <span class="sign">s</span><span class="expn">eeeeeee e</span><span class="mant">mmmmmmm mmmmmmmm mmmmmmmm</span><br />
  64 bits: <span class="cont">11111000</span> <span class="sign">s</span><span class="expn">eeeeeee eeee</span><span class="mant">mmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm</span>
</p>

<p>You’ll notice in the 14-, 21-, 35-, and 64-bit cases that if the least significant bits of the mantissa stored in the prefix are all <code class="language-plaintext highlighter-rouge">0</code> the rest are the standard 8-, 16-, 32-, and 64-bit encodings:</p>

<p class="codeblock">
   8 bits: <span class="cont">10</span><span class="mant">000000</span> <span class="sign">s</span><span class="expn">eeee</span><span class="mant">mmm</span><br />
  16 bits: <span class="cont">110</span><span class="mant">00000</span> <span class="sign">s</span><span class="expn">eeeee</span><span class="mant">mm mmmmmmmm</span><br />
  32 bits: <span class="cont">11110</span><span class="mant">000</span> <span class="sign">s</span><span class="expn">eeeeeee e</span><span class="mant">mmmmmmm mmmmmmmm mmmmmmmm</span><br />
  64 bits: <span class="cont">11111000</span> <span class="sign">s</span><span class="expn">eeeeeee eeee</span><span class="mant">mmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm</span>
</p>

<p>As with the varints those are nice fast cases to have.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>There is no standard canonical 8-bit format. I’ve gone with 4 exponent bits, 3 mantissa bits, and a bias of 7. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Christian Plesner Hansen</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Bigger Better Varints</title><link href="http://h14s.p5r.org/2024/11/11/bigger-better-varints.html" rel="alternate" type="text/html" title="Bigger Better Varints" /><published>2024-11-11T21:52:00+01:00</published><updated>2024-11-11T21:52:00+01:00</updated><id>http://h14s.p5r.org/2024/11/11/bigger-better-varints</id><content type="html" xml:base="http://h14s.p5r.org/2024/11/11/bigger-better-varints.html"><![CDATA[<style>
  .cont { color: #b00000 }
</style>

<p>I recently found myself needing a varint encoding. There are lots of those around but especially after reading about some of the gymnastics people have been doing to make LEB128 fast I decided to try to come up with something more efficient. I’ll describe that format, LPV256, below.</p>

<p>Just to rehash, LEB128 works by chopping a given number into 7-bit groups and then chaining them together. For instance, the integer 1234567 in binary is</p>

<p class="codeblock">
100101101011010000111
</p>

<p>Chop that into 7-bit groups like so<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>,</p>

<p class="codeblock">
1001011 0101101 0000111
</p>

<p>Add a top bit that is <code class="language-plaintext highlighter-rouge">0</code> for the last group and <code class="language-plaintext highlighter-rouge">1</code> for all the others:</p>

<p class="codeblock">
<span class="cont">1</span>1001011 <span class="cont">1</span>0101101 <span class="cont">0</span>0000111
</p>

<p>(I’ll call the top bit the <em>continuation</em> bit since <code class="language-plaintext highlighter-rouge">1</code> means “there are more blocks coming” and <code class="language-plaintext highlighter-rouge">0</code> means “this is the last block”)</p>

<p>Using this pattern you can encode any integer value and the smaller the value the shorter the encoded representation. Neat.</p>

<p>The problem is that to decode this you need to check the continuation bit for each block separately<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup>. A straightforward implementation would need at least 3 branches to decode a 3-byte value. That’s not great for performance. One common approach to try to fix this is to <a href="https://research.google.com/people/jeff/WSDM09-keynote.pdf">shuffle the continuation bits around</a>. If you’re okay with only encoding 32-bit values and reading them 4 at a time for instance you can take</p>

<p class="codeblock">
123456789 = 111010110111100110100010101 <br />
3456789   = 1101001011111100010101 <br />
56789     = 1101110111010101 <br />
89        = 1011001
</p>

<p>Chop them into groups of 8 bits,</p>

<p class="codeblock">
123456789 = 00000111 01011011 11001101 00010101 <br />
3456789   = 00110100 10111111 00010101 <br />
56789     = 11011101 11010101 <br />
89        = 01011001
</p>

<p>Prefix each one with the number of bytes, encoded so that <code class="language-plaintext highlighter-rouge">00</code> means 1 byte, <code class="language-plaintext highlighter-rouge">01</code> means 2, and so on:</p>

<p class="codeblock">
123456789 = <span class="cont">11</span> 00000111 01011011 11001101 00010101 <br />
3456789   = <span class="cont">10</span> 00110100 10111111 00010101 <br />
56789     = <span class="cont">01</span> 11011101 11010101 <br />
89        = <span class="cont">00</span> 01011001
</p>

<p>Finally shuffle all the prefixes together into the first byte, followed by the encoded numbers</p>

<p class="codeblock">
<span class="cont">11100100</span> 00000111 01011011 11001101 <br />
00010101 00110100 10111111 00010101 <br />
11011101 11010101 01011001
</p>

<p>These 11 bytes encode the 4 numbers and the first byte tells you what the layout is: first a 4-byte, then a 3-byte, then a 2-byte, and finally a 1-byte value. This means you can decode the whole thing with just a single branch on the first byte. Very efficient.</p>

<p>However, this only works if you can limit yourself to 32-bit values and if you’re reading the values sequentially. That doesn’t work for what I’m doing. I want to be able to represent very large values, for instance cryptographic hashes, GUIDs, and the like. They are large integers too, we just don’t usually store them as such. Also I want to be able to access values randomly rather than reading them sequentially. So this scheme just doesn’t work.</p>

<p><a href="https://github.com/ip7z/7zip/blob/e008ce3976c087bfd21344af8f00a23cf69d4174/DOC/7zFormat.txt#L111">7z</a> uses a model that also shuffles the continuation bits together into a prefix but it does for each varint, rather than for 4 at a time. If we take the 4 numbers from the example before you can think of it as sort of using the same approach as LEB128 but with a twist. Again you chop the values into blocks of 7 bits</p>

<p class="codeblock">
123456789 = 0111010 1101111 0011010 0010101 <br />
3456789   = 0000001 1010010 1111110 0010101 <br />
56789     = 0000011 0111011 1010101 <br />
89        = 1011001
</p>

<p>Then for each you add a prefix that encodes the length in unary: 1 block is <code class="language-plaintext highlighter-rouge">0</code>, 2 blocks is <code class="language-plaintext highlighter-rouge">10</code>, 3 blocks is <code class="language-plaintext highlighter-rouge">110</code>, 4 is <code class="language-plaintext highlighter-rouge">1110</code>, and so on. So you get</p>

<p class="codeblock">
123456789 = <span class="cont">1110</span> 0111010 1101111 0011010 0010101 <br />
3456789   = <span class="cont">1110</span> 0000001 1010010 1111110 0010101 <br />
56789     = <span class="cont">110</span> 0000011 0111011 1010101 <br />
89        = <span class="cont">0</span> 1011001
</p>

<p>You’ll note that the prefix always has as many bits as the number of blocks, so the total length of the prefix plus the blocks will always be a multiple of 8. So we divide the whole value, including the prefix, into blocks of 8 instead of 7,</p>

<p class="codeblock">
123456789 = <span class="cont">1110</span>0111 01011011 11001101 00010101 <br />
3456789   = <span class="cont">1110</span>0000 00110100 10111111 00010101 <br />
56789     = <span class="cont">110</span>00000 11011101 11010101 <br />
89        = <span class="cont">0</span>1011001
</p>

<p>Now you can tell just from looking at the first byte how long the value is: find the most significant <code class="language-plaintext highlighter-rouge">0</code> bit, the number will be as long as the number of <code class="language-plaintext highlighter-rouge">1</code> bits above it plus one. So you only need one branch per value. The limitation is that when you get to 64-bit values you run out of space in the prefix byte. And I want values larger than 64 bits.</p>

<p>So here is what I ended up with. I do exactly the same as 7z for values that fit within 35 bits:</p>

<p class="codeblock">
 7 bits: <span class="cont">0</span>xxxxxxx<br />
14 bits: <span class="cont">10</span>xxxxxx xxxxxxxx<br />
21 bits: <span class="cont">110</span>xxxxx xxxxxxxx xxxxxxxx<br />
28 bits: <span class="cont">1110</span>xxxx xxxxxxxx xxxxxxxx xxxxxxxx<br />
35 bits: <span class="cont">11110</span>xxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
</p>

<p>Above 35 bits the scheme changes. Instead of the prefix containing the length as well as some of the value itself, the whole first byte says how long the value that follows is:</p>

<p class="codeblock">
  64 bits: <span class="cont">11111000</span> + 8 b<br />
 128 bits: <span class="cont">11111001</span> + 16 b<br />
 256 bits: <span class="cont">11111010</span> + 32 b<br />
 512 bits: <span class="cont">11111011</span> + 64 b<br />
1024 bits: <span class="cont">11111100</span> + 128 b<br />
2048 bits: <span class="cont">11111101</span> + 256 b<br />
   unused: <span class="cont">1111111</span>x
</p>

<p>This way you can represent up to 2048-bit numbers which is not infinite but significantly more than the estimated number of particles in the observable universe<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">3</a></sup>. It’s plenty good enough for my use.</p>

<p>These schemes are usually called some opaque abbreviation so I’ll call this LPV256, LPV for Little-endian Prefix Variant, and the 256 is because it can represent up to 256-byte values.</p>

<p>This tradeoff, being able to decode values with a single branch and also being able to represent very large values, isn’t free. It means that some values take up more space than if we were using LEB128. To get a sense for how much, here is a graph of how many bytes it takes to represent a <em>n</em>-bit number in both representations up to 64 bits. (Smaller is better).</p>

<p><img src="/assets/2024/11/comparison-64.png" alt="comparison 64" /></p>

<p>Up to 35 bits it’s the same, then there’s a range where LEB128 is smaller or the same, and then LPV256 is slightly smaller for full 64-bit values.</p>

<p>This might look like a bad tradeoff when you just see it. between 36 and 57 bits LEB128 is smaller, and only from 57 to 64 is LPV256 as small or smaller. That makes it look like LEB128 is smaller around 70% of the time. But that’s misleading. Each increase in bit count doubles the number of values so in reality, if you pick a random 64-bit value there is a less than 1% chance that it lands within the range where LEB128 is smaller. And there’s a 50% chance that it lands within the range where LPV256 is strictly smaller.</p>

<p>This is only looking at values up to 64 bits. If we go up to 256 bits the pattern is similar,</p>

<p><img src="/assets/2024/11/comparison-256.png" alt="comparison 256" /></p>

<p>This isn’t that meaningful a comparison because you wouldn’t store values that large as LEB128. Here’s why: the number of branches it takes to decode values,</p>

<p><img src="/assets/2024/11/branches-256.png" alt="branches 256" /></p>

<p>To decode a 256-bit value encoded as LEB128 would require 37 branches and 37 bits of arithmetic to build the result. And until you meed the 37’th byte you don’t know that what you’re building is a 256-bit value which makes building the result even more expensive. With LPV256 you know when you read the first byte that it’s a 256-bit value and it takes no work to construct the result, it can be read directly from the 32 bytes following the prefix.</p>

<h3 id="big-or-little-prefix">Big or little prefix?</h3>

<p>One thing that’s worth considering is: in the case where we store a bit of the value within the prefix, do we store the most or least significant bits of the value? It would seem more little-endian to store the least significant bits first but there are good reasons to be big-endian and store the most significant first. If we expect to often store 8-, 16-, and 32-bit values then those will be stored as the 14-, 21-, and 35-bit variants respectively. Here’s how an 8-bit value (let’s use <code class="language-plaintext highlighter-rouge">255</code>) would be stored with a little-endian prefix:</p>

<p class="codeblock">
<span class="cont">10</span>111111 00000011
</p>

<p>and here it is with a big-endian prefix:</p>

<p class="codeblock">
<span class="cont">10</span>000000 11111111
</p>

<p>In the first case you need to do arithmetic to shift the least significant bits from the prefix into the result. In the second case the result is right there in the second byte, and you can recognize that it is just by looking at the first byte. The same is the case for 16- and 32-bit values. So it permits a fast path in some cases I expect are common.</p>

<p>You can think of it as extending the scheme used for bigger values, where the prefix holds no bits from the value, into the smaller ones:</p>

<p class="codeblock">
 8 bits: <span class="cont">10000000</span> + 1 b<br />
16 bits: <span class="cont">11000000</span> + 2 b<br />
24 bits: <span class="cont">11100000</span> + 3 b<br />
32 bits: <span class="cont">11110000</span> + 4 b<br />
64 bits: <span class="cont">11111000</span> + 8 b<br />
…
</p>

<p>Whether you view the prefix <code class="language-plaintext highlighter-rouge">10000000</code> as the tag for an 8-bit value or as the prefix of a 14-bit value where the top 6 bits happen to be 0 doesn’t matter. Both are equally valid views and the result is the same.</p>

<p>Besides providing a useful fast case it is helpful for instance in patching. Say you want to write a block of data, starting with a varint that gives the size. If you know the size up front no problem but if you only know the size after you’ve actually written the data, as long as you know it will fit within say 32 bits you can write a placeholder 32-bit zero where the size goes,</p>

<p class="codeblock">
<span class="cont">11110000</span> 00000000 00000000 00000000 00000000
</p>

<p>Then once you’re done writing the data and know the length you can go back and write the size as a plain 32-bit int in the 4 last bytes without having to touch the prefix. If the low bits go in the prefix then you would have to do nontrivial work to get the encoding right.</p>

<p>That does mean that if the size turns out to be say 17 it has to be legal to encode that as a 35-bit value. We can’t require that you use the smallest possible representation, in this case that would a 7-bit value. But there’s little to be gained from requiring that anyway.</p>

<p>I’ll write more about what I need this for but I thought it was an interesting bit of design in itself.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>I’m being a little sloppy with the endianness but it should be little endian everywhere. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>You can be arbitrarily clever here, for instance you might shuffle the continuation bits of the next 8 bytes together into a single byte before you dispatch, that way you only dispatch once per 8 encoded bytes. That works but has a lot of corner cases, it only works if you’re reading multiple values together, and the shuffling isn’t exactly free. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3" role="doc-endnote">
      <p>If we estimate that there’s 10<sup>89</sup> particles in the visible universe, that’s roughly 2<sup>296</sup> so 512 bits is actually enough for there to be a unique value for each particle. <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Christian Plesner Hansen</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Bitwise division</title><link href="http://h14s.p5r.org/2023/02/bitwise-division.html" rel="alternate" type="text/html" title="Bitwise division" /><published>2023-02-26T13:38:14+01:00</published><updated>2023-02-26T13:38:14+01:00</updated><id>http://h14s.p5r.org/2023/02/bitwise-division</id><content type="html" xml:base="http://h14s.p5r.org/2023/02/bitwise-division.html"><![CDATA[<p>Integer division is expensive. Much more expensive than multiplication. Much, much more expensive than addition. If you’re trying to make some integer operations really fast it’s bad news if you need to do division.</p>

<p>A while ago, for a hobby project, I happened to be playing around with variable-length integer encodings. Where you store integers such that small ones take up less space than large ones. This is the kind of thing you want to be very fast indeed. At one point I ended up with this expression on a hot code path:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(63 - nlz) / 7
</code></pre></div></div>

<p>For everything else I could come up with fast ways of doing it using bitwise operations but this one place I ended up with division. And in this case not only is it expensive it’s overkill: the value we’re dividing by is a constant and in this case <code class="language-plaintext highlighter-rouge">nlz</code> is known to be between 0 and 63.</p>

<p>I thought: I’ll experiment a bit and see if I can’t come up with some bitwise operations that work just like dividing by 7 when the input is between 0 and 63. The one kind of division that is very cheap is by a power of 2, that’s just bit shifting. And it happens to be the case that <code class="language-plaintext highlighter-rouge">7 * 9 = 63</code>, which is almost <code class="language-plaintext highlighter-rouge">64</code>, a power of 2. Putting those together I got something I thought might do the trick:</p>

\[\frac{v}{7} = \frac{9 v}{9 \times 7} = \frac{9 v}{63} \approx \frac{9 v}{64}\]

<p>This you can compute with bitwise operations!</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(9 * v) / 64
= (9 * v) &gt;&gt; 6
= (v + 8 * v) &gt;&gt; 6
= (v + (v &lt;&lt; 3)) &gt;&gt; 6
</code></pre></div></div>

<p>Not bad! An expression that is purely bitwise operations but that computes <em>almost</em> division by 7. How “almost”? It turns out that this works for <code class="language-plaintext highlighter-rouge">0</code> to <code class="language-plaintext highlighter-rouge">6</code> but gives the wrong answer for 7: it yields <code class="language-plaintext highlighter-rouge">0</code> where it should be <code class="language-plaintext highlighter-rouge">1</code>. Okay, it’s off by 1 – let’s try adding 1 then:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(v + (v &lt;&lt; 3) + 1) &gt;&gt; 6
</code></pre></div></div>

<p>Now it’s correct from <code class="language-plaintext highlighter-rouge">0</code> to <code class="language-plaintext highlighter-rouge">13</code> but gives the wrong answer for <code class="language-plaintext highlighter-rouge">14</code>: <code class="language-plaintext highlighter-rouge">1</code> where it should be <code class="language-plaintext highlighter-rouge">2</code>. So let’s try adding <code class="language-plaintext highlighter-rouge">2</code> instead of 1. That makes it works for <code class="language-plaintext highlighter-rouge">0</code> to <code class="language-plaintext highlighter-rouge">20</code>. If we keep increasing the fudge factor as long as we keep getting the right answer we end up with:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(v + (v &lt;&lt; 3) + 9) &gt;&gt; 6
</code></pre></div></div>

<p>This computes <code class="language-plaintext highlighter-rouge">v / 7</code> correctly for <code class="language-plaintext highlighter-rouge">v</code> from <code class="language-plaintext highlighter-rouge">0</code> to <code class="language-plaintext highlighter-rouge">69</code> which was what I needed originally. Actually I only needed up to <code class="language-plaintext highlighter-rouge">63</code>.</p>

<p>Excellent! Problem solved! So let’s get back to varint encoding? Well, now I was on my way down the rabbit hole of bitwise division. What if it wasn’t <code class="language-plaintext highlighter-rouge">7</code> I needed to divide by, could I do something similar for other values? Where did the limit of <code class="language-plaintext highlighter-rouge">69</code> come from, and the fudge factor of <code class="language-plaintext highlighter-rouge">9</code>?</p>

<h2 id="lets-generalize">Let’s generalize</h2>

<p>A quick recap: because <code class="language-plaintext highlighter-rouge">7 * 9 = 64 - 1</code> we can implement <code class="language-plaintext highlighter-rouge">v / 7</code> like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(9 * v + 9) / 64
= (v + (v &lt;&lt; 3) + 9) &gt;&gt; 6
</code></pre></div></div>

<p>for <code class="language-plaintext highlighter-rouge">v</code> between <code class="language-plaintext highlighter-rouge">0</code> and <code class="language-plaintext highlighter-rouge">69</code>.</p>

<p>Put more abstractly: given a divisor <em>d</em>, which happened to be 7, we found a power of 2, 64 = 2<sup>6</sup>, such that</p>

\[d m = 2^n - 1\]

<p>for a multiplier value <em>m</em> which in this case was <code class="language-plaintext highlighter-rouge">9</code>.</p>

<p>Using this together with a fudge factor <em>a</em> which also turned out to be <code class="language-plaintext highlighter-rouge">9</code>, we were able to replace division by <em>d</em> with</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(m * v + a) &gt;&gt; n
</code></pre></div></div>

<p>which gives the correct result for values between 0 and some limit <em>L</em>, where <em>L</em> in this case was <code class="language-plaintext highlighter-rouge">69</code>.</p>

<p>Now, what if I wanted to divide by some other value than 7? Let’s say 43? Then we have to find an <em>n</em> such that</p>

\[43 m = 2^n - 1\]

<p>for some <em>m</em>. That just means an <em>n</em> such that 43 is a factor in 2<sup><em>n</em></sup>-1. I’ve put a table of the prime factors of 2<sup><em>n</em></sup>-1s at the bottom. There is one: 2<sup>14</sup>-1.</p>

\[43 \times 381 = 2^{14} - 1\]

<p>So you can replace <code class="language-plaintext highlighter-rouge">v / 43</code> with</p>

<p><code class="language-plaintext highlighter-rouge">(381 * v + a) &gt;&gt; 14</code></p>

<p>for some choice of <em>a</em>, and then it will be correct for values up to some limit <em>L</em>. What should <em>a</em> be and what will that make <em>L</em>? Well, let’s try to derive them. Let’s start with <em>a</em>. (And just skip the derivations if this kind of stuff bores you).</p>

<p>One thing that definitely must hold is that if you bitwise-divide 0 by <em>d</em> the result must be 0:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(m * 0 + a) &gt;&gt; n = 0
</code></pre></div></div>

\[\left\lfloor{\frac{0 m + a}{2^n}}\right\rfloor = 0\]

\[\left\lfloor{\frac{a}{2^n}}\right\rfloor = 0\]

\[0 \le a &lt; 2^n\]

<p>So we know that definitely the fudge factor must be non-negative. Similarly if you bitwise-divide <em>d</em>-1 by <em>d</em> the result must also be 0; that gives us:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(m * (d - 1) + a) &gt;&gt; n = 0
</code></pre></div></div>

\[\left\lfloor{\frac{(d - 1)m + a}{2^n}}\right\rfloor = 0\]

\[0 \le (d - 1)m + a &lt; 2^n\]

\[0 \le md - m + a &lt; 2^n\]

\[0 \le 2^n - 1 - m + a &lt; 2^n\]

\[-1 - m + a &lt; 0\]

\[a &lt; m + 1\]

<p>Putting those two together we get that</p>

\[0 \le a \le m\]

<p>But which <em>a</em> to choose? There we can use the fact that bitwise division increases more slowly then real division so when it gets the answer wrong, it’ll be because it returns too small a value. So we want <em>a</em> to be the largest allowed value: <em>m</em>.</p>

<p>Next, let’s derive <em>L</em>. Or, let’s derive <em>L</em>+1, the first value where bitwise division yields the wrong result. Since bitwise division grows more slowly than division that will be at some multiple of <em>d</em>, <em>k d</em>, where it yields a value less than the true result: <em>k</em> - 1.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(m * k * d + m) &gt;&gt; n = k - 1
</code></pre></div></div>

\[\left\lfloor\frac{m k d + m}{2^n}\right\rfloor = k - 1\]

\[2^n(k-1) \le m k d + m &lt; 2^nk\]

\[2^n(k-1) \le (2^n-1)k + m &lt; 2^nk\]

\[2^n(k-1) \le 2^nk - k + m &lt; 2^nk\]

\[-2^n \le m - k &lt; 0\]

\[m &lt; k\]

<p>The smallest <em>k</em> which yields a wrong result is hence the first value greater than <em>m</em>: <em>m</em> + 1 so that makes <em>L</em>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>L + 1 = k * d
L + 1 = (m + 1) * d
L = (m + 1) * d - 1
</code></pre></div></div>

<p>Just to verify let’s try the example from before: 7</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>L = (9 + 1) * 7 - 1
= 69
</code></pre></div></div>

<p>Another useful way to write this is</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>L = (m + 1) * d - 1
= (m * d) + d - 1
= (1 &lt;&lt; n) - 1 + d - 1
= (1 &lt;&lt; n) + (d - 2)
</code></pre></div></div>

<p>This means that for any <em>d</em> &gt; 2 <em>L</em> is at least 2<sup>n</sup>. That gives a nice rule of thumb: the bitwise division by 43 above holds for all values up to 2<sup>14</sup>. And then a bit more.</p>

<p>Can you always find a value of <em>n</em> that lets you do bitwise division? In theory probably yes, I’m not good enough at number theory to say definitively. But since in practice we’re working with finite numbers  you usually want <em>n</em> to be less than 32 and then the answer, at least initially, is no. Here are some values that you can’t bitwise divide with an <em>n</em> at most 32:</p>

<p>37, 53, 59, 61, 67, 71, 79, 83, 97</p>

<p>Does that mean that if we end up having to divide by 37 there is no way to express that as a bitwise operation? No. This exact approach doesn’t work but there are others. For instance, so far we’ve only looked at <em>dm</em>  = 2<sup>n</sup>-1. There’s also <em>dm</em> = 2<sup>n</sup>+1 – maybe we can use that when 2<sup>n</sup>-1 doesn’t work? (Spoiler: yes we can, not always but often). What about <em>dm</em> = 2<sup>n</sup>-2, might that be useful somehow? There’s more fun to be had with this. But that’s for another post.</p>

<h2 id="appendix">Appendix</h2>

<p>Prime factors of 2<sup><em>n</em></sup> - 1 for <em>n</em> up to 32 (<a href="https://en.wikipedia.org/wiki/Mersenne_prime">Mersenne primes</a> marked in bold).</p>

<table>
  <thead>
    <tr>
      <th><em>n</em></th>
      <th>prime factors of 2<sup><em>n</em></sup> - 1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>2</strong></td>
      <td>3</td>
    </tr>
    <tr>
      <td><strong>3</strong></td>
      <td>7</td>
    </tr>
    <tr>
      <td>4</td>
      <td>3, 5</td>
    </tr>
    <tr>
      <td><strong>5</strong></td>
      <td>31</td>
    </tr>
    <tr>
      <td>6</td>
      <td>3, 3, 7</td>
    </tr>
    <tr>
      <td><strong>7</strong></td>
      <td>127</td>
    </tr>
    <tr>
      <td>8</td>
      <td>3, 5, 17</td>
    </tr>
    <tr>
      <td>9</td>
      <td>7, 73</td>
    </tr>
    <tr>
      <td>10</td>
      <td>3, 11, 31</td>
    </tr>
    <tr>
      <td>11</td>
      <td>23, 89</td>
    </tr>
    <tr>
      <td>12</td>
      <td>3, 3, 5, 7, 13</td>
    </tr>
    <tr>
      <td><strong>13</strong></td>
      <td>8191</td>
    </tr>
    <tr>
      <td>14</td>
      <td>3, 43, 127</td>
    </tr>
    <tr>
      <td>15</td>
      <td>7, 31, 151</td>
    </tr>
    <tr>
      <td>16</td>
      <td>3, 5, 17, 257</td>
    </tr>
    <tr>
      <td><strong>17</strong></td>
      <td>131071</td>
    </tr>
    <tr>
      <td>18</td>
      <td>3, 3, 3, 7, 19, 73</td>
    </tr>
    <tr>
      <td><strong>19</strong></td>
      <td>524287</td>
    </tr>
    <tr>
      <td>20</td>
      <td>3, 5, 5, 11, 31, 41</td>
    </tr>
    <tr>
      <td>21</td>
      <td>7, 7, 127, 337</td>
    </tr>
    <tr>
      <td>22</td>
      <td>3, 23, 89, 683</td>
    </tr>
    <tr>
      <td>23</td>
      <td>47, 178481</td>
    </tr>
    <tr>
      <td>24</td>
      <td>3, 3, 5, 7, 13, 17, 241</td>
    </tr>
    <tr>
      <td>25</td>
      <td>31, 601, 1801</td>
    </tr>
    <tr>
      <td>26</td>
      <td>3, 2731, 8191</td>
    </tr>
    <tr>
      <td>27</td>
      <td>7, 73, 262657</td>
    </tr>
    <tr>
      <td>28</td>
      <td>3, 5, 29, 43, 113, 127</td>
    </tr>
    <tr>
      <td>29</td>
      <td>233, 1103, 2089</td>
    </tr>
    <tr>
      <td>30</td>
      <td>3, 3, 7, 11, 31, 151, 331</td>
    </tr>
    <tr>
      <td><strong>31</strong></td>
      <td>2147483647</td>
    </tr>
    <tr>
      <td>32</td>
      <td>3, 5, 17, 257, 65537</td>
    </tr>
  </tbody>
</table>

<p>Reverse index: for a prime, which 2<sup><em>n</em></sup>-1s is it a factor of:</p>

<table>
  <thead>
    <tr>
      <th>p</th>
      <th>n where p is a prime factor of 2 <sup><em>n</em></sup>-1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>3</strong></td>
      <td>2, 4, 6, 6, 8, 10, 12, 12, 14, 16, 18, 18, 18, 20, 22, 24, 24, 26, 28, 30, 30, 32</td>
    </tr>
    <tr>
      <td>5</td>
      <td>4, 8, 12, 16, 20, 20, 24, 28, 32</td>
    </tr>
    <tr>
      <td><strong>7</strong></td>
      <td>3, 6, 9, 12, 15, 18, 21, 21, 24, 27, 30</td>
    </tr>
    <tr>
      <td>11</td>
      <td>10, 20, 30</td>
    </tr>
    <tr>
      <td>13</td>
      <td>12, 24</td>
    </tr>
    <tr>
      <td>17</td>
      <td>8, 16, 24, 32</td>
    </tr>
    <tr>
      <td>19</td>
      <td>18</td>
    </tr>
    <tr>
      <td>23</td>
      <td>11, 22</td>
    </tr>
    <tr>
      <td>29</td>
      <td>28</td>
    </tr>
    <tr>
      <td><strong>31</strong></td>
      <td>5, 10, 15, 20, 25, 30</td>
    </tr>
    <tr>
      <td>41</td>
      <td>20</td>
    </tr>
    <tr>
      <td>43</td>
      <td>14, 28</td>
    </tr>
    <tr>
      <td>47</td>
      <td>23</td>
    </tr>
    <tr>
      <td>73</td>
      <td>9, 18, 27</td>
    </tr>
    <tr>
      <td>89</td>
      <td>11, 22</td>
    </tr>
    <tr>
      <td>113</td>
      <td>28</td>
    </tr>
    <tr>
      <td><strong>127</strong></td>
      <td>7, 14, 21, 28</td>
    </tr>
    <tr>
      <td>151</td>
      <td>15, 30</td>
    </tr>
    <tr>
      <td>233</td>
      <td>29</td>
    </tr>
    <tr>
      <td>241</td>
      <td>24</td>
    </tr>
    <tr>
      <td>257</td>
      <td>16, 32</td>
    </tr>
    <tr>
      <td>331</td>
      <td>30</td>
    </tr>
    <tr>
      <td>337</td>
      <td>21</td>
    </tr>
    <tr>
      <td>601</td>
      <td>25</td>
    </tr>
    <tr>
      <td>683</td>
      <td>22</td>
    </tr>
    <tr>
      <td>1103</td>
      <td>29</td>
    </tr>
    <tr>
      <td>1801</td>
      <td>25</td>
    </tr>
    <tr>
      <td>2089</td>
      <td>29</td>
    </tr>
    <tr>
      <td>2731</td>
      <td>26</td>
    </tr>
    <tr>
      <td><strong>8191</strong></td>
      <td>13, 26</td>
    </tr>
    <tr>
      <td>65537</td>
      <td>32</td>
    </tr>
    <tr>
      <td><strong>131071</strong></td>
      <td>17</td>
    </tr>
    <tr>
      <td>178481</td>
      <td>23</td>
    </tr>
    <tr>
      <td>262657</td>
      <td>27</td>
    </tr>
    <tr>
      <td><strong>524287</strong></td>
      <td>19</td>
    </tr>
    <tr>
      <td><strong>2147483647</strong></td>
      <td>31</td>
    </tr>
  </tbody>
</table>]]></content><author><name>Christian Plesner Hansen</name></author><summary type="html"><![CDATA[Integer division is expensive. Much more expensive than multiplication. Much, much more expensive than addition. If you’re trying to make some integer operations really fast it’s bad news if you need to do division.]]></summary></entry><entry><title type="html">World history is off by one</title><link href="http://h14s.p5r.org/2019/12/world-history-is-off-by-one.html" rel="alternate" type="text/html" title="World history is off by one" /><published>2019-12-16T20:16:50+01:00</published><updated>2019-12-16T20:16:50+01:00</updated><id>http://h14s.p5r.org/2019/12/world-history-is-off-by-one</id><content type="html" xml:base="http://h14s.p5r.org/2019/12/world-history-is-off-by-one.html"><![CDATA[<p>New years eve 2019 is only a few weeks away. The end of the decade. The last day of the 2010, then the first of the 2020s.</p>

<p>Or is it?</p>

<p>This post is about calendars and how we assign numbers to years. I’ll explain why, if you look closely at them, years like 120 BC, AD 14, and 2019, aren’t as straightforward as you might think. Then I’ll describe the off-by-one error that has led to all this confusion rippling down through the centuries: the year that should be year 0 but isn’t. Finally I’ll suggest a different way of counting years that makes most of this confusion go away.</p>

<p>Let’s start off with a <a href="https://www.youtube.com/watch?v=fofcLXshq_8">classic exchange</a> from Seinfeld (S8E20, “The Millennium”):</p>

<blockquote>
  <p><strong>Jerry</strong>: By the way, Newman, I’m just curious, when you booked the hotel, did you book it for the millennium new year?</p>

  <p><strong>Newman</strong>: As a matter of fact, I did.</p>

  <p><strong>Jerry</strong>: Oh that’s interesting, because, as everyone knows since there was no year zero, the millennium doesn’t begin until 2001, which would make your party one year late, and thus, quite lame. Oooooh.</p>

  <p><strong>Newman</strong>: <em>squawnk</em></p>
</blockquote>

<p>Wait, what? I’m old enough to remember that the big millennium new year was on the evening of December 31, 1999. Wasn’t it? I’m pretty sure it was.</p>

<h3 id="whats-in-a-millennium">What’s in a millennium?</h3>

<p>Let’s say Jerry is right – and in fact he is – that this millennium only started in 2001. What does that make the year 2000? Which century is it in? Is it in the twentieth or twenty-first century? The twentieth century is the 1900s right so surely it’s not in that? If the 1900s means anything it must be years that start with 19. So it must be the twenty-first century? But then that would mean that on new years eve of 1999 we went from the twentieth to the twenty-first century. But since we’re assuming Jerry is right we then had to wait until 2001 to go from the second to the third millennium. That sounds all wrong though, centuries and millenniums must match up, and decades too. Speaking of that, which decade is 2000 in? Surely it’s not in the 1990’s right, surely. Right?</p>

<p>Okay so you may suspect that I’m deliberately making this sound more confusing that it is, and I am; sorry about that. It does actually all make sense – sort of – but is still a little unexpected.</p>

<p>The core question is: what is a millennium, a century, a decade? The answer is that <em>any</em> period of 1000 years is a millennium, <em>any</em> period of 100 years is a century and <em>any</em> period of 10 years is a decade. So the years 1990-1999 is a decade but so is 1945-1954. Similarly the years 1000-1999 is a millennium but so is 454-1453. None of these terms have anything to do with <em>where</em> on the time scale they occur, they’re just periods of a particular number of years.</p>

<p>This means that the first millennium is the first sequence of 1000 years, wherever they fall on the timeline. As Jerry says, because there is no year 0 the first year is AD 1. A thousand years later is AD 1000 so that’s the first millennium: AD 1 up to and including AD 1000. The first year of the second millennium is AD 1001 and the last is AD 2000. So we did indeed only enter the new millennium in 2001.</p>

<p>It works the same way for centuries and decades. The first century was AD 1 to AD 100, the second was AD 101 to AD 200, and so. Following it all the way up to our time you get that the twentieth century covers 1901 to 2000. So I was really lying before when I said that the twentieth century was the same as the 1900s. Each have one year that is not in the other: the 1900s have 1900 which is in nineteenth century, and the twentieth century has 2000 which is not in the 1900s.</p>

<p>Similarly, to come back to this coming new years eve: the 2010s do indeed end when we leave 2019 – but the second decade of our century actually keeps going for another year until the end of 2020. So it’s the end of the decade but it also isn’t because “this decade” has two possible meanings.</p>

<h3 id="jesus">Jesus!</h3>

<p>Let’s take a quick detour and talk about what AD means. We usually leave out the “AD” when we talk about modern years, nobody calls it 2019 AD, but the AD is there implicitly. And it’s what all this confusion springs from.</p>

<p>AD means <em>Anno Domini</em>, literally “in the year of the lord”, the lord in question being Jesus. It’s really an exercise in religious history, one that goes back to the darkest middle ages, so maybe it’s not surprising if modern pedants like me stumble over the mathematics of it.</p>

<p>Already at this point, before we’ve even gone into where AD comes from, things become murky. Consider this. If 2019 means “2019 years since the birth of Jesus”, and we assume Jesus was born in December, how old would he turn in December 2019? Presumably 2019 should be the year he turns 2019 right? But if he was born in AD 1 his 1-year birthday would have been in AD 2 and then 2019 is the year of his 2018’th birthday. He would have had to be born in 1 BC for the years to match up. But 1 BC is expressly <em>not</em> a “year of the lord”. Either the years don’t match up or Jesus – the actual lord – lived, at least briefly, in a year that wasn’t “of the lord”.</p>

<p>The first person to count years <em>Anno Domini</em> was a monk, Dionysius the Humble. (Side note: imagine a person so humble that he stands out among monks as <em>the humble one</em>). Back then, in the early 500s, the most common way to indicate a year was by who was roman consul that year. The year Dionysius invented AD would have been known to him and everyone else at the time as “the year of the consulship of Probus Junior”. But he was working on a table of when Easter would fall for the following century and when you’re dealing with 50 or 100 years into the future how do you denote years? You don’t know who will be consul. Dionysius decided to instead count years “since the incarnation of our Lord Jesus Christ”. By this scheme his present year was 525. How did he decide that at that moment it had been 525 years since the “incarnation”? We don’t really know, though some people have theories.</p>

<p>Note that this means that when historians argue that Jesus was more likely born between 6 BC and 4 BC they’re not disagreeing with the bible, the bible doesn’t specify a particular year. It was Dionysius, much later, who decided the year so he’s the one they’re disagreeing with.</p>

<p>In any case Dionysius wasn’t clear in his writing on what “since the incarnation” actually means so we don’t know if he believed Jesus was born in 1 BC or AD 1. The question from before about Jesus’ age doesn’t have a clear answer, at least not based on how years are counted. Most assume he meant 1 BC so the years and Jesus’ birthdays match up but we’re really not sure.</p>

<h3 id="year-zero">Year Zero</h3>

<p>Now let’s backtrack a little to where we were before this little historical diversion: the off-by-one error in how we count years. The year numbers (1900s) and the ordinals (twentieth century) are misaligned.</p>

<p>It actually gets worse when you bring BC into it.</p>

<p>Here’s a little quiz. Take a moment to figure them out but don’t feel bad if you give up, they’re meant to be a little tricky. Also don’t worry about dates, assume that events all happened on the same calendar date.</p>

<ul>
  <li>The Napoleonic wars started in 1803 and ended in 1815. How many years was this?</li>
  <li>Johann Sebastian Bach was born in 1685. Was that towards the beginning or the end of the 1600s? He died in 1750. How many years did he live?</li>
  <li>Julius Caesar was in a relationship with Cleopatra. He was born in 100 BC, she in 69 BC. What was their age difference?</li>
  <li>Mithridates the Great was born in 120 BC. Was that towards the beginning or the end of the 100s BC? He died in 63 BC. How many years did he live?</li>
  <li>Phraates V ruled Persia from 4 BC to AD 2. How many years did he rule?</li>
</ul>

<p>Notice how the questions are basically the same but they get harder? I’m the one who made them up and I struggled to solve the last three ones myself, or at least struggled to convince myself that my answers were correct. But let’s go through the answers.</p>

<ul>
  <li>The Napoleonic wars lasted 1815 - 1803 = 12 years.</li>
  <li>The year Bach was born, 1685, is towards the end of the 1600s and he lived 65 years: 15 years until 1700 and 50 years after, 65 in total.</li>
  <li>The age difference between Caesar and Cleopatra was 31 years because time counts backwards BC. 31 years on from 100 BC is 69 BC.</li>
  <li>Mithridates was born towards the end of the 100s BC. Again, in BC the years count backwards so 120 BC means there’s 20 years left of that century, not that 20 years have passed like it would in AD. He lived 57 years: 20 years until 100 BC and then, again because time counts backwards in BC, 37 years until 63 BC.</li>
  <li>Phraates ruled for 5 years. You’d think it should be 6: 4 years BC and 2 years AD, 6 in total – but there is no year 0, we skip directly from 1 BC to AD 1, so it’s really 5.</li>
</ul>

<p>This highlights two issues with how we count years: it’s easy to work with modern years – we do it all the time – but everything gets turned upside down when you go to BC. You have to fight your normal understanding of what a year means – for instance the 20s of a century is now in the end, not the beginning. And you have to watch out especially for the missing year between 1 BC and AD 1.</p>

<p>There are models like astronomical time that insert a year 0 – or rather it renames 1 BC to 0 – and that helps a lot. But I don’t find it intuitive to work with negative years. For instance, I still have to turn off my normal intuition to get that -120 is before -115, not after.</p>

<p>I’m interested in ancient history and so I’ve stubbed my toe on this over and over again. I’ve also given some thought to what a more intuitive system might look like. What I’ve come up with, as a minimum, is: you would want to redefine BC 1 to be 0 AD. You would want years to always move forward; it’s more intuitive for the years’ names to move the same way as time: always forward. Finally you would want the years AD to stay unchanged since those are the ones we use every day, there’s no way to change those.</p>

<h3 id="how-about-this">How about this?</h3>

<p>Here is a system that has those properties.</p>

<p>Like in astronomy you redefine BC 1 to be 0 AD. Other than that we leave AD unchanged. In BC you reverse how you count the years but only <em>within each century</em>. So the years count up both during BC and AD but the <em>centuries</em> BC still count backwards. Finally, to distinguish it from what we currently do, rather than write BC after or AD before you would write a <strong>B</strong> or <strong>A</strong> between the centuries and the years. This also makes it clear that the centuries and years within them are treated differently, sort of how we usually separate hours and minutes with a colon: <strong>7:45</strong> rather than <strong>745</strong>.</p>

<p>What does that look like? Here are some examples:</p>

<ul>
  <li>525 AD is unchanged but can be written as 5A25 if you want to be really explicit.</li>
  <li>BC 1 is year zero AD and is written as 0 or, again if you want to be really explicit, 0A00.</li>
  <li>BC 2 is the last year of the first century BC so that’s 0B99. Since we’re always counting forwards the last year of any century is 99, like centuries AD.</li>
  <li>BC 3 is the year before 0B99 so 0B98. When going backwards in time we count the years backwards so the year before is one less.</li>
  <li>BC 34 is 0B67 because it’s 33 years before the end of the first century BC. Just like 1967 is 33 years before 2000.</li>
  <li>BC 134 is 1B67, just like BC 34 is 0B67. Only the years within the centuries are changed, the centuries stay the same (with a single exception).</li>
</ul>

<p>There’s a simple general rule for converting the doesn’t require you to think, I’ll get to that in a second. First I’ll illustrate that this is indeed more intuitive by revisiting some questions from before but now written with this new system:</p>

<ul>
  <li>Julius Caesar was in a relationship with Cleopatra. He was born in 0B01, she in 0B32. What was their age difference?</li>
  <li>Mithridates the Great was born in 1B81. Was that towards the beginning or the end of the 1B00s? He died in 0B38. How many years did he live?</li>
  <li>Phraates V ruled Persia from 0B97 to 2. How many years did he rule?</li>
</ul>

<p>I would suggest that it’s now a lot closer to how you normally think about years. Also, the ADs are no longer off by one: the first century starts in year 0 and runs 100 years, to year 99. The twentieth starts in 1900 making the millennium new year 1999. If only they’d used this system Newman’s party wouldn’t have been late, and thus, not lame.</p>

<p>The numbers are written differently, at least in BC where they actually are different, so it’s clear which system is being used. Converting from BC is straightforward.</p>

<ol>
  <li>Any year BC that ends in 01 becomes year zero in the next century. For instance, 201 BC (the year the Second Punic War ended) becomes 1B00 and 1001 BC (the year Zhou Mu Wang becomes king) becomes 9B00.</li>
  <li>Any other year you keep the century and subtract the year from 101. For instance for 183 BC (the year Scipio Africanus died), the century stays 1 and the year is 101 - 83 = 18. So that’s 1B18.</li>
</ol>

<p>(Technically you don’t need the first rule because when the year is 01, 101 - 01 = 100 which you can interpret as adding one to the century and setting the year to 00.)</p>

<p>It’s maybe a little cumbersome for the person writing if they’re used to BC/AD but it’s the same kind of operation you already need to do to understand years BC in the first place. And I would suggest that the result is easier for the person reading and that hopefully more people read than write a given text. It’s the same kind of operation to go back to BC though I’ll leave that as an exercise for the reader.</p>

<p>A small but relevant point is: how do you pronounce these? I would suggest still saying BC and AD but between the century and year rather than after the whole number. So where you would say “one eighty-three b-c” for 183 BC, with the new system you would say “one b-c eighteen” for the equivalent year 1B18. For the first century BC, “thirty-four b-c” for 34 BC becomes “zero b-c sixty-seven” for the equivalent 0B67.</p>

<p>That’s it. I’m curious what anyone else thinks. If one day there was an opportunity to change how years are written – like there was for measurements during the French revolution – would this be a sensible model to switch to? If not, is there another model that’s better?</p>]]></content><author><name>Christian Plesner Hansen</name></author><summary type="html"><![CDATA[New years eve 2019 is only a few weeks away. The end of the decade. The last day of the 2010, then the first of the 2020s.]]></summary></entry><entry><title type="html">More Than Voronoi</title><link href="http://h14s.p5r.org/2018/08/more-than-voronoi.html" rel="alternate" type="text/html" title="More Than Voronoi" /><published>2018-08-11T01:25:10+02:00</published><updated>2018-08-11T01:25:10+02:00</updated><id>http://h14s.p5r.org/2018/08/more-than-voronoi</id><content type="html" xml:base="http://h14s.p5r.org/2018/08/more-than-voronoi.html"><![CDATA[<p>This post is about a generalization of Voronoi diagram that I played around with. It’s probably not that useful but it’s a little fun math with an absolute ton of colorful diagrams.</p>

<p>It occurred to me a while ago that there was a generalization of Voronoi diagrams that maybe could be useful to something I was working on. As you know, a Voronoi diagram divides the plane into regions based on a set of points. Given the points, <em>p<sub>0</sub></em>, <em>p<sub>1</sub></em>, …, <em>p<sub>n</sub></em>, the region corresponding to <em>p<sub>i</sub></em> is the set of points that are closer to <em>p<sub>i</sub></em> than any of the other <em>p<sub>j</sub></em>. Here is an example of a run-of-the mill, standard, plain vanilla, Voronoi diagram:</p>

<p><img src="/assets/2018/08/cartesian-ordered-1.png" alt="" width="320" height="320" /></p>

<p>This diagram determines which points are closer using normal, cartesian, distance but Voronoi diagrams also make sense for other kinds of distance, for instance Manhattan distance:</p>

<p><img src="/assets/2018/08/manhattan-unordered-1.png" alt="" width="320" height="320" /></p>

<p>The generalization that occurred to me was: if a region in a plain Voronoi diagram is defined by the one point it is closest to, what if you defined a diagram where regions are based on the two closest points? That is, for each pair of points, <em>p<sub>i</sub></em> and <em>p<sub>j</sub></em>, there would be a region made up of points where the closest point is <em>p<sub>i</sub></em> and the second-closest is <em>p<sub>j</sub></em>. What would that look like, I wondered. I searched around and it’s definitely a thing, it’s called a higher-order Voronoi diagram, but I couldn’t find any actual diagrams.</p>

<p>There may be some established terminology around this but I ended up using my own names: I would call what I just described a Voronoi<sup>2</sup> diagram, and a plain one would be a Voronoi<sup>1</sup>. (From here on I’ll call the region around <em>p<sub>i</sub></em> in the Voronoi<sup>1</sup> diagram <em>V</em>(<em>p<sub>i</sub></em>), and the region around <em>p<sub>i</sub></em> and <em>p<sub>j</sub></em> in the Voronoi<sup>2</sup> diagram I’ll call <em>V</em>(<em>p<sub>i</sub></em>, <em>p<sub>j</sub></em>)).</p>

<p>You can kind of guess just from the definition that a Voronoi<sup>2</sup> would look similar to the corresponding Voronoi<sup>1</sup> just more subdivided. For any given <em>p<sub>i</sub></em>, the point’s region in the Voronoi<sup>1</sup> diagram, <em>V</em>(<em>p<sub>i</sub></em>), is the set of point closest to <em>p<sub>i</sub></em>. Well for any point in that set they will have some other point <em>p<sub>j</sub></em> as their second-closest, and so if you take the union over all <em>p<sub>j</sub></em> of <em>V</em>(<em>p<sub>i</sub></em>, <em>p<sub>j</sub></em>) that gives you <em>V</em>(<em>p<sub>i</sub></em>). So the regions in a Voronoi<sup>2</sup> diagram are basically fragments of regions of the Voronoi<sup>1</sup>.</p>

<p>Below is the same diagram as before, for comparison, and the Voronoi<sup>2</sup> diagram.</p>

<p><img src="/assets/2018/08/cartesian-ordered-1-2.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-ordered-2-5.png" alt="" width="320" height="320" /></p>

<p>As you can see, that is exactly what the Voronoi<sup>2</sup> diagram looks like: each Voronoi<sup>1</sup> region has been subdivided into sub-regions, one for each of its neighboring points. You can do the same thing for the Manhattan diagrams,</p>

<p><img src="/assets/2018/08/manhattan-unordered-1-2.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-ordered-2-1.png" alt="" width="320" height="320" /></p>

<p>Now we’ve defined Voronoi<sup>1</sup> and Voronoi<sup>2</sup> but why stop there when we could keep going and define Voronoi<sup>3</sup>. This would be, you’ve probably already guessed it, a diagram with a region for each choice of <em>p<sub>i</sub></em>, <em>p<sub>j</sub></em>, and <em>p<sub>k</sub></em>, that is made up of the points that have <em>p<sub>i</sub></em> as their closest point, <em>p<sub>j</sub></em> as their second-closest, and <em>p<sub>k</sub></em> as their third-closest. Let’s call such a region <em>V</em>(<em>p<sub>i</sub></em>, <em>p<sub>j</sub></em>, <em>p<sub>k</sub></em>). As I’m sure you’ve already guessed the Voronoi<sup>3</sup> regions are further subdivisions of the Voronoi<sup>2</sup> regions:</p>

<p><img src="/assets/2018/08/cartesian-ordered-1-1.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-ordered-2-4.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/cartesian-ordered-3.png" alt="" width="320" height="320" /></p>

<p>And the Manhattan version,</p>

<p><img src="/assets/2018/08/manhattan-unordered-1-3.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-ordered-2-2.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/manhattan-ordered-3.png" alt="" width="320" height="320" /></p>

<p>The images are becoming smaller but you can click them to see larger versions.</p>

<p>From here you can just keep going: Voronoi<sup>4</sup>, Voronoi<sup>5</sup>, Voronoi<sup>6</sup>, and so on and so on. Which of course I did, what did you expect? Here are Voronoi<sup>1</sup>-Voronoi<sup>8</sup> with cartesian distance,</p>

<p><img src="/assets/2018/08/cartesian-ordered-1-3.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-ordered-2-6.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/cartesian-ordered-3-1.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-ordered-4.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/cartesian-ordered-5.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-ordered-6.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/cartesian-ordered-7.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-ordered-8.png" alt="" width="320" height="320" /></p>

<p>and the same with Manhattan distance</p>

<p><img src="/assets/2018/08/manhattan-unordered-1-4.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-ordered-2-3.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/manhattan-ordered-3-1.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-ordered-4.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/manhattan-ordered-5.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-ordered-6.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/manhattan-ordered-7.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-ordered-8.png" alt="" width="320" height="320" /></p>

<p>Except… I lied before when I said you could just keep going. In this example there are 8 points so the Voronoi<sup><em>n</em></sup> diagrams are only well-defined for <em>n</em> up to 8 – that’s why there’s 8 diagrams above. And indeed if you look closely diagram 7 and 8 are actually the same – because once you’ve picked 7 points there is no choice for the last point, there is only the 8th left, so the diagrams end up looking exactly the same.</p>

<p>So is that it – is that all the colorful diagrams we get? Well, there is just one last tweak we can make to get a different kind of diagram.</p>

<p>The thing is, in the definition of Voronoi<sup>2</sup> we said that <em>V</em>(<em>p<sub>i</sub></em>, <em>p<sub>j</sub></em>) was the points where <em>p<sub>i</sub></em> is the closest point and <em>p<sub>j</sub></em> is the second-closest. That is, the order of <em>p<sub>i</sub></em> and <em>p<sub>j</sub></em> is significant. An alternative definition we could use would be one where we don’t consider the order, where the region doesn’t care whether it’s <em>p<sub>i</sub></em> closest and <em>p<sub>j</sub></em> second-closest, or <em>p<sub>j</sub></em> closest and <em>p<sub>i</sub></em> second-closest. I’ll call this <em>V<sub>u</sub></em>(<em>p<sub>i</sub></em>, <em>p<sub>j</sub></em>) (the <em>u</em> is for unordered).</p>

<p>You’ll notice right away that by this definition <em>V<sub>u</sub></em>(<em>p<sub>i</sub></em>, <em>p<sub>j</sub></em>)=<em>V<sub>u</sub></em>(<em>p<sub>j</sub></em>, <em>p<sub>i</sub></em>) so there’s a lot fewer regions. Here’s an example of a Voronoi<sub>u</sub><sup>1</sup> (which is the same as the Voronoi<sup>1</sup>) and Voronoi<sub>u</sub><sup>2</sup> diagram,</p>

<p><img src="/assets/2018/08/cartesian-unordered-1-1.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-unordered-2.png" alt="" width="320" height="320" /></p>

<p>With these unordered diagrams it can be a little trickier to figure out which two points a region actually corresponds to, especially in cases where the points in question are far away from the region. The trick you can use in this case is that for a given region is in the Voronoi<sub>u</sub><sup>2</sup>, if you look at the same place in the Voronoi<sup>1</sup> there will be a dividing line that goes across where the region is in the Voronoi<sub>u</sub><sup>2</sup>, from one corner of the region to another. The two points on either side of the Voronoi<sup>1</sup> will be the one the region corresponds to.</p>

<p>The same things works, as always, with Manhattan distance:</p>

<p><img src="/assets/2018/08/manhattan-ordered-1.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-unordered-2.png" alt="" width="320" height="320" /></p>

<p>An interesting thing happens if we plot all the Voronoi<sub>u</sub><sup><em>n</em></sup> all the way up to 8:</p>

<p><img src="/assets/2018/08/cartesian-unordered-1-2.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-unordered-2-1.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/cartesian-unordered-3.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-unordered-4.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/cartesian-unordered-5.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-unordered-6.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/cartesian-unordered-7.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/cartesian-unordered-8.png" alt="" width="320" height="320" /></p>

<p>The number of regions stays about the same and when we get to Voronoi<sub>u</sub><sup>7</sup> and Voronoi<sub>u</sub><sup>8</sup> they actually become simpler. This is because at that point the set of points for a given region includes almost all the points so the determining factor becomes which are the few points that aren’t in the set – and at 7 and 8 there’s 1 and 0 left respectively. So whereas Voronoi<sup>8</sup> was useless because it’s the same as Voronoi<sup>7</sup>, here it’s useless because there’s only one region that contains all the points.</p>

<p>Is this construction at all useful? I’m not sure, I imagine it could be but I don’t have any particular use for them myself. Really I was just curious what it would look like.</p>

<p>I’ll leave you with a last set of diagrams, Voronoi<sub>u</sub><sup>1</sup> to Voronoi<sub>u</sub><sup>8</sup> for Manhattan distance.</p>

<p><img src="/assets/2018/08/manhattan-unordered-1-5.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-unordered-2-1.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/manhattan-unordered-3.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-unordered-4.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/manhattan-unordered-5.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-unordered-6.png" alt="" width="320" height="320" /></p>

<p><img src="/assets/2018/08/manhattan-unordered-7.png" alt="" width="320" height="320" /> <img src="/assets/2018/08/manhattan-unordered-8.png" alt="" width="320" height="320" /></p>]]></content><author><name>Christian Plesner Hansen</name></author><summary type="html"><![CDATA[This post is about a generalization of Voronoi diagram that I played around with. It’s probably not that useful but it’s a little fun math with an absolute ton of colorful diagrams.]]></summary></entry><entry><title type="html">Stdout is a dead end</title><link href="http://h14s.p5r.org/2015/12/stdout-is-a-dead-end.html" rel="alternate" type="text/html" title="Stdout is a dead end" /><published>2015-12-18T11:42:42+01:00</published><updated>2015-12-18T11:42:42+01:00</updated><id>http://h14s.p5r.org/2015/12/stdout-is-a-dead-end</id><content type="html" xml:base="http://h14s.p5r.org/2015/12/stdout-is-a-dead-end.html"><![CDATA[<p>I haven’t written much about it on this blog but the project I’ve been working on full time for the last two years is a new kind of terminal, <em>chorus</em>. Current terminals are a relic of the past and chorus is my take on a modern replacement.</p>

<p>I’ve created a blog specifically about chorus, the <a href="http://t.undra.org/chorus/blog/">chorus console blog</a>. There I’ll be writing about the approach I’m taking and my thoughts about what terminals are and where they should be moving. The title of this post itself hints at where I see them evolving. But you can read more about that in the <a href="http://t.undra.org/chorus/blog/2015/12/07/chorus-a-new-kind-of-terminal/">introductory post</a>.</p>]]></content><author><name>Christian Plesner Hansen</name></author><summary type="html"><![CDATA[I haven’t written much about it on this blog but the project I’ve been working on full time for the last two years is a new kind of terminal, chorus. Current terminals are a relic of the past and chorus is my take on a modern replacement.]]></summary></entry><entry><title type="html">A simple way to pre-scramble a sequence</title><link href="http://h14s.p5r.org/2015/11/a-simple-way-to-pre-scramble-a-sequence.html" rel="alternate" type="text/html" title="A simple way to pre-scramble a sequence" /><published>2015-11-26T11:56:07+01:00</published><updated>2015-11-26T11:56:07+01:00</updated><id>http://h14s.p5r.org/2015/11/a-simple-way-to-pre-scramble-a-sequence</id><content type="html" xml:base="http://h14s.p5r.org/2015/11/a-simple-way-to-pre-scramble-a-sequence.html"><![CDATA[<p>I have this problem where I need to try something a number of times, maybe 64 times, and each time with a different small seed, say a value between 0 and 1024. I’d like the seeds to be reasonably scrambled and I don’t want to see the same one more than once. I also need the same order every time, that’s what I mean by <em>pre-scrambling</em> – the scrambling isn’t dynamic, it’s hardcoded. How do I do this in a simple way without resorting to say just hard coding a list of numbers?</p>

<p>What I’d really like to do is use something like a random number generator but with pre-determined set parameters that I know will generate the numbers I want. The xorshift generator seems like a good candidate because it’s really simple but the quality is decent. It requires 4 parameters, x, y, z, and w, and then you can generate a sequence of values in the following way, where limit is the size of the set you want to generate:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">t</span> <span class="o">=</span> <span class="n">x</span> <span class="o">^</span> <span class="p">(</span><span class="n">x</span> <span class="o">&lt;&lt;</span> <span class="mi">11</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">y</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">z</span>
<span class="n">z</span> <span class="o">=</span> <span class="n">w</span>
<span class="n">w</span> <span class="o">=</span> <span class="p">(</span><span class="n">w</span> <span class="o">^</span> <span class="p">(</span><span class="n">w</span> <span class="o">&gt;&gt;</span> <span class="mi">19</span><span class="p">)</span> <span class="o">^</span> <span class="n">t</span> <span class="o">^</span> <span class="p">(</span><span class="n">t</span> <span class="o">&gt;&gt;</span> <span class="mi">8</span><span class="p">))</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span>
<span class="k">return</span> <span class="n">w</span> <span class="o">%</span> <span class="n">limit</span>
</code></pre></div></div>

<p>This is what I’d like to use – I just need some parameters. And it turns out that there are parameters that will make it behave like I want. Here’s an example,</p>

<p><em>0x31f12daf 0x6dd97342 0xda4daacd 0x41235c71</em>: 85/<strong>256</strong> 85 (33.2% 1x)</p>

<p>This means: with these parameters <em>x y z w</em> and a limit of 256 you get 85 different values (that’s the 85 in “85/256”) if you execute the xorshift code 85 times (that’s the second 85), which means that you’re covering 33.2% of the possible values and executing the loop 1x per unique generated value. Here are some seeds for different limits that are powers of 2, that generate a pretty big set of unique values,</p>

<p><em>0x2735e8f4 0x9fcb0c3e 0xd0c18064 0x0f6b0093</em>: 26/<strong>32</strong> 26 (81.2% 1x)</p>

<p><em>0x1ff079d6 0x54248059 0xc968e911 0x38c15c75</em>: 39/<strong>64</strong> 39 (60.9% 1x)</p>

<p><em>0xf8efc789 0x88a40b37 0x86f01aa6 0x15384f52</em>: 59/<strong>128</strong> 59 (46.1% 1x)</p>

<p><em>0x31f12daf 0x6dd97342 0xda4daacd 0x41235c71</em>: 85/<strong>256</strong> 85 (33.2% 1x)</p>

<p><em>0xfd8193d0 0xc8b69d8f 0xa42b9d1c 0x7e69d727</em>: 133/<strong>512</strong> 133 (26% 1x)</p>

<p><em>0x4617b049 0xf7a49270 0xa88b568c 0x32dff77c</em>: 174/<strong>1024</strong> 174 (17% 1x)</p>

<p>As an example of how to use one of these, here’s how you’d use the first line, the one that generates values with a limit of 32, in python:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">generate</span><span class="p">():</span>
  <span class="n">x</span> <span class="o">=</span> <span class="mh">0x2735e8f4</span>
  <span class="n">y</span> <span class="o">=</span> <span class="mh">0x9fcb0c3e</span>
  <span class="n">z</span> <span class="o">=</span> <span class="mh">0xd0c18064</span>
  <span class="n">w</span> <span class="o">=</span> <span class="mh">0x0f6b0093</span>
  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">26</span><span class="p">):</span>
    <span class="n">t</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span> <span class="o">^</span> <span class="p">(</span><span class="n">x</span> <span class="o">&lt;&lt;</span> <span class="mi">11</span><span class="p">))</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">y</span>
    <span class="n">y</span> <span class="o">=</span> <span class="n">z</span>
    <span class="n">z</span> <span class="o">=</span> <span class="n">w</span>
    <span class="n">w</span> <span class="o">=</span> <span class="p">(</span><span class="n">w</span> <span class="o">^</span> <span class="p">(</span><span class="n">w</span> <span class="o">&gt;&gt;</span> <span class="mi">19</span><span class="p">)</span> <span class="o">^</span> <span class="n">t</span> <span class="o">^</span> <span class="p">(</span><span class="n">t</span> <span class="o">&gt;&gt;</span> <span class="mi">8</span><span class="p">))</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span>
    <span class="k">yield</span> <span class="n">w</span> <span class="o">%</span> <span class="mi">32</span>

<span class="k">print</span> <span class="nf">list</span><span class="p">(</span><span class="nf">generate</span><span class="p">())</span>
</code></pre></div></div>

<p>This prints</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[2, 18, 9, 30, 12, 0, 19, 17, 7, 5, 14, 16, 6, 24, 15, 4, 3,
31, 10, 29, 8, 23, 11, 22, 1, 26]
</code></pre></div></div>

<p>which, and you can check if you want, are 26 different values between 0 and 32.</p>

<p>If you can tolerate some duplicates you can get better coverage. If you can only tolerate a few, say about one duplicate in 16 values, you can get,</p>

<p><em>0xf852d2f8 0xaf137287 0x6a0d4795 0x326c8a41</em>: 28/<strong>32</strong> 29 (87.5% 1x)</p>

<p><em>0xa8683488 0x361c1383 0xbc95298a 0xe4c57646</em>: 46/<strong>64</strong> 49 (71.9% 1.1x)</p>

<p><em>0xca30a753 0x317aa350 0x1bc8bee2 0xce4830bf</em>: 79/<strong>128</strong> 87 (61.7% 1.1x)</p>

<p><em>0xe079cdb3 0x7cb29574 0x45eebac8 0xeb8dcefc</em>: 132/<strong>256</strong> 147 (51.6% 1.1x)</p>

<p><em>0xf41e4441 0x3345d823 0x608ff840 0x554f5cdd</em>: 238/<strong>512</strong> 269 (46.5% 1.1x)</p>

<p><em>0x201ceef2 0x7f49ce17 0x0bd10615 0x139bfa7b</em>: 423/<strong>1024</strong> 485 (41.3% 1.1x)</p>

<p>So for example in the 256 case, if you generate 147 values with the given seed you’ll hit 132 different values between 0 and 256, and the rest will be duplicates. That’s a lot better coverage than the 85 you could hit if you didn’t allow them.</p>

<p>If you can tolerate even more duplicates, say you don’t mind hitting roughly one on average per unique value, you can get close to full coverage</p>

<p><em>0xa9bb0026 0xe0178ff2 0x443fd052 0x9fe0d459</em>: 32/<strong>32</strong> 41 (100% 1.3x)</p>

<p><em>0x4c19f4c7 0x1d253873 0x5c1f6f17 0x812944fc</em>: 64/<strong>64</strong> 106 (100% 1.7x)</p>

<p><em>0x854fbffe 0x5aa965d5 0x06ff8c3e 0xd5057351</em>: 127/<strong>128</strong> 252 (99.2% 2x)</p>

<p><em>0xeb03a458 0x26ae990e 0x6227aaee 0x192b3cb7</em>: 242/<strong>256</strong> 496 (94.5% 2x)</p>

<p><em>0x97bbc402 0x20470416 0x09ce179b 0xbf276b7d</em>: 469/<strong>512</strong> 980 (91.6% 2.1x)</p>

<p><em>0x6d36254c 0x19c5f46a 0x1614da1a 0xcfadbfc8</em>: 915/<strong>1024</strong> 1939 (89.4% 2.1x)</p>

<p>As an example, running the same python code from above but now with parameters from this set you get,</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[19, 27, 10, 12, 18, 16, 13, 15, 24, 4, 23, 11, 28, 30, 26,
19, 24, 1, 12, 15, 29, 2, 19, 8, 9, 20, 6, 5, 17, 3, 14, 31,
22, 25, 18, 27, 8, 20, 0, 7, 21]
</code></pre></div></div>

<p>In this list of length 41 all numbers between 0 and 31 occur, but 8, 12, 15, 18, 20, 24, and 27 are there twice and 19 is there three times.</p>

<p>Finally, if you don’t care how many times you try as long as you generate <em>all</em> the numbers that’s possible too. At this point you probably want to keep track of which value you’ve seen, maybe with a bit vector, and just filter the raw values you generate.</p>

<p><em>0xa9bb0026 0xe0178ff2 0x443fd052 0x9fe0d459</em>: 32/<strong>32</strong> 41 (100% 1.3x)</p>

<p><em>0x4c19f4c7 0x1d253873 0x5c1f6f17 0x812944fc</em>: 64/<strong>64</strong> 106 (100% 1.7x)</p>

<p><em>0xf3bd4634 0xb1442411 0xd536236f 0x3beae2fb</em>: 128/<strong>128</strong> 291 (100% 2.3x)</p>

<p><em>0x1c608f31 0x34e54bbd 0xa799c7a8 0x78af6664</em>: 256/<strong>256</strong> 729 (100% 2.8x)</p>

<p><em>0x10bace53 0x88bc0781 0xd815fe20 0xc77bcbec</em>: 512/<strong>512</strong> 1786 (100% 3.5x)</p>

<p><em>0xb6c93670 0xb89f9de6 0x3ba3713c 0x78bcabc7</em>: 1024/<strong>1024</strong> 4341 (100% 4.2x)</p>

<p>If you look closely you’ll notice that the parameters are the same as before for some limits, that’s because we already had perfect coverage before so there’s nothing to improve. And as the set grows you can see that the number of times you have to try grows, so at 1024 you need to loop 4341 times before you’ve seen all values. And note also that the duplicates aren’t evenly distributed, the further you get the more work you have to do to get a value you haven’t seen before.</p>

<p>Of limited use I guess but if this is the kind of thing you need, pretty convenient. I’ve dumped the code I used to generate these in a <a href="https://gist.github.com/plesner/a003f7a108345c56a74a">gist</a>.</p>]]></content><author><name>Christian Plesner Hansen</name></author><summary type="html"><![CDATA[I have this problem where I need to try something a number of times, maybe 64 times, and each time with a different small seed, say a value between 0 and 1024. I’d like the seeds to be reasonably scrambled and I don’t want to see the same one more than once. I also need the same order every time, that’s what I mean by pre-scrambling – the scrambling isn’t dynamic, it’s hardcoded. How do I do this in a simple way without resorting to say just hard coding a list of numbers?]]></summary></entry><entry><title type="html">Piping into a desktop indicator</title><link href="http://h14s.p5r.org/2015/04/piping-into-a-desktop-indicator.html" rel="alternate" type="text/html" title="Piping into a desktop indicator" /><published>2015-04-14T11:09:02+02:00</published><updated>2015-04-14T11:09:02+02:00</updated><id>http://h14s.p5r.org/2015/04/piping-into-a-desktop-indicator</id><content type="html" xml:base="http://h14s.p5r.org/2015/04/piping-into-a-desktop-indicator.html"><![CDATA[<p>This post is about interacting with the graphical desktop environment from a shell script. Specifically: say you have a long-running bash script and you’d like to keep an eye on it through a unity app indicator. How do you make that work in an appropriately unix-y way? (If you’re not sure what I mean see the animation below).</p>

<p>Background. Over the weekend I finally changed from NFS to rsync for keeping my source code in sync across machines. Much better if my network connection is unreliable and fewer moving parts. After I was done with the basics though I thought: I really need to be able to keep an eye on how syncing is going. It’s just the worst to spend ages unsuccessfully trying to reproduce an issue on a virtual machine only to realize that it’s because the code I’m running isn’t being properly synced when I edit files on my laptop.</p>

<p>Here’s what I had in mind: when I run the code change monitor shell script I want to get an app indicator in the top bar that changes state when a sync is going on, so I can see that syncing actually happening and whether it’s slow. And I want it to show if there are any errors. This, in other words</p>

<p><img src="/assets/2015/04/sync.gif" alt="sync" width="432" height="272" /></p>

<p>The syncing logic itself is straightforward: one component uses <code class="language-plaintext highlighter-rouge">inotifywait</code> to wait for files to change (<code class="language-plaintext highlighter-rouge">watchdog.sh</code>), then calls out to a script that does the actual sync (<code class="language-plaintext highlighter-rouge">do-rsync.sh</code>).</p>

<p>How to show the indicator though? There is no command-line api for this kind of thing and I wasn’t sure what it would look like if there was. Also, the existing code was properly unix-y and I wanted it to stay that way. One component knows how to wait for changes but knows nothing about rsync; the rsync part knows how to do a single sync but doesn’t care when or why it is being called. They only meet at the top level,</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>watchdog.sh <span class="nt">--root</span> <span class="nb">.</span> ./do-rsync.sh
</code></pre></div></div>

<p>What I ended up with was a python script, <code class="language-plaintext highlighter-rouge">sync-indicator.py</code>, that was responsible for just the indicator. When it starts it creates the indicator and then waits around, reading input from stdin. When it sees a command in the output it recognizes, say <code class="language-plaintext highlighter-rouge">[SYNC: syncing]</code>, it consumes that line and changes the state of the indicator. Anything that doesn’t match is just passes straight through to stdout. Here’s what it looks like,</p>

<p><img src="/assets/2015/04/pipe.gif" alt="pipe" width="384" height="240" /></p>

<p>This way the indicator logic doesn’t need to know about the watching or rsyncing, and those parts don’t need to know about the indicator. All you need to do is change the toplevel command that puts it all together to,</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>watchdog.sh <span class="nt">--root</span> <span class="nb">.</span> ./do-sync-and-indicate.sh | ./sync-indicator.py
</code></pre></div></div>

<p>where <code class="language-plaintext highlighter-rouge">do-sync-and-indicate.sh</code> is a trivial wrapper around <code class="language-plaintext highlighter-rouge">do-sync.sh</code> that looks like this,</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="nb">echo</span> <span class="s2">"[SYNC: syncing]"</span>
<span class="k">if</span> ./do-sync.sh<span class="p">;</span> <span class="k">then
  </span><span class="nb">echo</span> <span class="s2">"[SYNC: idle]"</span>
<span class="k">else
  </span><span class="nb">echo</span> <span class="s2">"[SYNC: error]"</span>
<span class="k">fi</span>
</code></pre></div></div>

<p>You can even replace this with a generic command that takes another command as an argument and all it does is call that command surrounded with appropriate <code class="language-plaintext highlighter-rouge">SYNC</code> messages.</p>

<p>Pretty clean and unix-y I think, independent components and so on.  The python indicator script itself, <a href="https://gist.github.com/plesner/ea6a808c1e1c382ec567">sync-indicator.py</a>, is straightforward, only 60ish lines with comments.</p>

<p>The ease of supporting this makes me wonder though. Why aren’t long-running commands better at interacting with the desktop?</p>]]></content><author><name>Christian Plesner Hansen</name></author><summary type="html"><![CDATA[This post is about interacting with the graphical desktop environment from a shell script. Specifically: say you have a long-running bash script and you’d like to keep an eye on it through a unity app indicator. How do you make that work in an appropriately unix-y way? (If you’re not sure what I mean see the animation below).]]></summary></entry><entry><title type="html">Making tea</title><link href="http://h14s.p5r.org/2015/01/making-tea.html" rel="alternate" type="text/html" title="Making tea" /><published>2015-01-14T17:58:59+01:00</published><updated>2015-01-14T17:58:59+01:00</updated><id>http://h14s.p5r.org/2015/01/making-tea</id><content type="html" xml:base="http://h14s.p5r.org/2015/01/making-tea.html"><![CDATA[<p>This post is about the mathematics of making a good cup of tea. I drink a lot of tea and for a long time I would ignore the direction to use water below boiling, say 75° or 85°. Because – if you don’t have a boiler with a temperature setting how do you get water at less than 100°? Wait for it to cool? Come on!</p>

<p>Of course you can do it easily by adding cold water, you just have to figure out how much. While I was waiting for a delivery this morning I thought I’d look into that and it turned out to be a fun little practical application of the scientific method.</p>

<h3 id="theory-1-the-average-temperature">Theory 1: the average temperature</h3>
<p>Let’s assume tap water is 22° and you add 500ml of it to the same amount of boiling water. My starting assumption was that the result will be 1l of water at the average of the two temperatures, 61°:</p>

\[t_r = \frac{100 \cdot 500 + 22 \cdot 500}{500 + 500}=61\]

<p>Put more generally, my theory was that if you mix water of two different temperatures then the temperature of the result will be the average over the two temperatures, where each temperature is weighted by the volume of water</p>

\[t_r = \frac{100 v_b + t_t v_t }{v_b + v_t}\]

<p>(Here \(t_r\) is the resulting temperature of the water, \(v_b\) is the amount of boiling water which will be 100°, \(t_t\) is the temperature of tap water, and \(v_t\) is the amount of tap water.)</p>

<p>If you measure the tap water temperature and know how much water your tea pot will hold you can solve for the amount of boiling and tap water to use to make any given water temperature. For instance, my tap water is 22° and my tea pot holds 700ml so the formula for how much to boil for a given temperature is,</p>

\[t_r = \frac{100 v_b + 22 (700 - v_b)}{700}\]

\[t_r = \frac{100 v_b + 22 \cdot 700 - 22 v_b}{700}\]

\[t_r = \frac{78 v_b + 22 \cdot 700}{700}\]

\[700 (t_r - 22) = 78 v_b\]

\[\frac{700}{78} (t_r - 22) = v_b\]

<p>So to get a pot full of 85° water, the amount of boiling water should be</p>

\[\frac{700}{78} (85 - 22) = 8.97 \cdot 63 = 565\]

<p>Boil 565ml, add the rest up to 700ml from the tap (that would be 135ml) and you’ve got 700ml of 85° water. That’s the theory.</p>

<p>Ok, so having solved the problem I went to make tea, my delivery having still not arrived (spoiler alert: it arrived while I was at the dentist, obviously). It turns out though that the theory doesn’t work. When I did it in practice it turned out that the water wasn’t 85°, it was 77°. Bummer. The theory is too simplistic.</p>

<h3 id="theory-2-the-tea-pot-constant">Theory 2: the tea pot constant</h3>
<p>The problem was fortunately obvious: I was pouring the water into a cold tea pot. The formula only says what happens to the water itself, it doesn’t take into account that it all ends up in a pot that’s initially at room temperature.</p>

<p>What I thought I’d do then was to model the effect of the cold pot as if it were extra tap water. How much exactly I don’t know, but it seems reasonable to expect that the cooling effect of a particular pot works basically the same way as if you’d added a bit of extra cold water. So we replace \(v_t\) in the formula above, the amount of tap water, with \(v_t + v_p\), the amount of tap water <em>and</em> some additional amount, \(v_p\), to account for the pot,</p>

\[t_r = \frac{100 v_b + t_t (v_t + v_p) }{v_b + v_t + v_p}\]

<p>You have to determine \(v_p\) experimentally, it is a property of a particular pot just like the volume. I determined it by pouring boiling water into the cool pot and then measuring the temperature; it had dropped to 90°. Using this I could find \(v_p\),</p>

\[t_r = \frac{100 v_b + t_t (v_t + v_p) }{v_b + v_t + v_p}\]

\[90 = \frac{100 \cdot 700 + 22 (0 + v_p) }{700 + v_p}\]

\[90 \cdot 700 + 90 v_p = 100 \cdot 700 + 22 v_p\]

\[-10 \cdot 700 = -68 v_p\]

\[\frac{10 \cdot 700}{68} = v_p = 103\]

<p>In other words: the pot cools boiling water as much as adding 103ml of extra tap water.</p>

<p>Again, it’s just a theory that this makes sense, but it’s a theory we can test. Earlier, I mixed 565ml boiling and 135ml tap water and got 77° instead of the 85° I expected. What does the new theory predict will happen?</p>

\[t_r = \frac{100 v_b + t_t (v_t + v_p) }{v_b + v_t + v_p}\]

\[t_r = \frac{100 \cdot 565 + 22 \left( 135 + 103 \right) }{700 + 103} = 76.9\]

<p>That’s so close to the 77° that you’d almost think I fudged the numbers, but it’s really just a coincidence.</p>

<p>With this new and more plausible general formula we can plug in the values for my pot and water and get a specific formula for how much boiling and tap water to use to produce a particular temperature in my pot,</p>

\[t_r = \frac{100 v_b + 22 (700 - v_b + 103)}{700 + 103}\]

\[t_r = \frac{100 v_b + 22 \cdot 803 - 22 v_b}{803}\]

\[t_r = \frac{78 v_b + 22 \cdot 803}{803}\]

\[803 (t_r - 22) = 78 v_b\]

\[\frac{803}{78} (t_r - 22) = v_b\]

<p>It turns out to be the same as the one before except with 803 instead of 700. Using this formula, then, to get 85° water I need</p>

\[\frac{803}{78} (85 - 22) = 10.29 \cdot 63 = 648\]

<p>ml of boiling and the rest, 52ml, of tap. I tried this out and the result was… drumroll… 86°. So the formula seems to work. Yay!</p>

<h3 id="summary">Summary</h3>
<p>So, to sum all this up, here’s how you apply the formulas in practice.</p>

<p>Measure how much water it takes to fill your pot, call that \(v\). Boil that much water and pour it into the pot. Measure the temperature and call that \(t_p\). Measure the temperature of your tap water, call that \(t_t\). Plug them into this formula to get the tea pot constant for your tea pot, \(v_p\)</p>

\[v_p = v \frac{t_p - 100}{t_t - t_p}\]

<p>Then, given a temperature \(t_r\), the amount of water to boil to get that temperature can be calculated by,</p>

\[v_b = \frac{(v+v_p) (t_r-t_t)}{100-t_t}\]

<p>And that’s it. You only have to calculate these once for a given pot so even though it’s a hassle, it’s a one time hassle. And it’s possible that most tea pots have approximately the same constant, in which case you can just assume that yours has the same one. But that’s for future research into the fertile field that is the science of tea.</p>

<p>Ironically, I got so caught up calculating the ideal amount of water that I never actually made tea, just water of different temperatures. I think I’ll go make some actual tea now.</p>]]></content><author><name>Christian Plesner Hansen</name></author><category term="mathematics" /><category term="misc" /><summary type="html"><![CDATA[This post is about the mathematics of making a good cup of tea. I drink a lot of tea and for a long time I would ignore the direction to use water below boiling, say 75° or 85°. Because – if you don’t have a boiler with a temperature setting how do you get water at less than 100°? Wait for it to cool? Come on!]]></summary></entry><entry><title type="html">Why I find IEEE 754 frustrating</title><link href="http://h14s.p5r.org/2014/11/why-i-find-ieee-754-frustrating.html" rel="alternate" type="text/html" title="Why I find IEEE 754 frustrating" /><published>2014-11-08T12:16:07+01:00</published><updated>2014-11-08T12:16:07+01:00</updated><id>http://h14s.p5r.org/2014/11/why-i-find-ieee-754-frustrating</id><content type="html" xml:base="http://h14s.p5r.org/2014/11/why-i-find-ieee-754-frustrating.html"><![CDATA[<blockquote>
  <p>Programming languages new (Java) and old (Fortran), and their compilers, still lack competent support for features of IEEE 754 so painstakingly provided by practically all hardware nowadays. <em>[…]</em> Programmers seem unaware that IEEE 754 is a standard for their programming environment, not just for hardware.</p>

  <p><a href="http://www.cs.berkeley.edu/~wkahan/ieee754status/754story.html">William Kahan</a></p>
</blockquote>

<p>This post is the result of me, a language design guy, trying and failing to figure out how to provide language bindings for IEEE 754 in a modern language. The TL;DR is,</p>

<ul>
  <li>
    <p>The basic model described in 754 is great, no complaints.</p>
  </li>
  <li>
    <p>The licensing terms of the spec document are deeply problematic.</p>
  </li>
  <li>
    <p>The language bindings are too specific and have an old-school procedural flavor that makes them difficult to apply to a modern language.</p>
  </li>
  <li>
    <p>It would be much more useful to know the motivation behind the design, that way each language can find a solution appropriate for them.</p>
  </li>
</ul>

<p>The rest of the post expands on these points. First off I’ll give some context about 754 and floating-point support in general.</p>

<h3 id="754">754</h3>
<p>I want to start out by saying that IEEE 754 has been enormously helpful for the world of computing. The fact that we have one ubiquitous and well-designed floating-point model across all major architectures, not multiple competing and less well designed models, is to a large extent thanks to 754. It’s been so successful that it’s easy to overlook what an achievement it was. Today it’s the water we swim in.</p>

<p>But 754 is two things, what I’ll call the <em>model</em> and the <em>bindings</em>. The model is a description of a binary floating-point representation and how basic operations on that representation should work. The bindings are a description of how a programming language should make this functionality available to programmers. The model is the part that’s been successful. The bindings, as Kahan, the driving force behing 754, admits, not so much.</p>

<p>I’ll go into more detail about why the bindings are problematic in a sec, it’s the main point of this post, but first I want to take a broader look at floating-point support in languages.</p>

<h3 id="floating-point-is-hard">Floating-point is hard</h3>
<p>I’m not really a numerical analysis guy at all, my interest is in language design (though as it happens the most popular blog post I’ve ever written, <a href="/2012/09/0x5f3759df.html">0x5f3759df</a>, is also about floating-point numbers). What interests me about floating-point (<em>FP</em> from now on) is that a couple of factors conspire to make it particularly difficult to get right in a language.</p>

<ol>
  <li>
    <p>Because floats are so fundamental, as well as for performance reasons, it’s difficult to provide FP as a library. They’re almost always part of the core of the language, the part the language designers design themselves.</p>
  </li>
  <li>
    <p>Numerical analysis is hard, it’s not something you just pick up if you’re not interested in it. Most language designers don’t have an interest in numerical analysis.</p>
  </li>
  <li>
    <p>A language can get away with incomplete or incorrect FP support. To quote James Gosling, “95% of the folks out there are completely clueless about floating-point.”</p>
  </li>
</ol>

<p>The goal of the binding part of 754 is, I think, to address the second point. Something along the lines of,</p>

<blockquote>
  <p>Dear language designers,</p>

  <p>We know you’re not at home in this domain and probably regret that you can’t avoid it completely. To help you out we’ve put together these guidelines, if you just follow them you’ll be fine.</p>

  <p>Much love,
The numerical analysts</p>
</blockquote>

<p>I think this is a great idea in principle. So what’s the problem?</p>

<h3 id="licensing">Licensing</h3>
<p>The most immediate problem is the licensing on the 754 document itself. Have you ever actually read it? I hadn’t until very recently. Do you ever see links from discussions around FP into the spec? I don’t, ever. There’s a reason for that and here it is,</p>

<p><img src="/assets/2014/11/ieee.png" alt="ieee" width="366" height="336" /></p>

<p>The document is simply not freely available. This alone is a massive problem. Before you complain that people don’t implement your spec maybe stop charging them $88 to even read it?</p>

<p>More insidiously, say I support 754 to the letter, how do I document it? What if I want to describe, in my language spec, under which circumstances a <em>divideByZero</em> is raised? This is what the spec says,</p>

<blockquote>
  <p>The divideByZero exception shall be signaled if and only if an exact infinite result is defined for an operation on finite operands. The default result of divideByZero shall be an ∞ correctly signed according to the operation <em>[… snip …]</em></p>
</blockquote>

<p>This sounds good to me as is. Can I copy it into my own spec or would that be copyright infringement? Can I write something myself that means the same? Or do I have to link to the spec and require my users to pay to read it? Even if I just say “see the spec”, might my complete implementation constitute infringement of a copyrighted <a href="https://en.wikipedia.org/wiki/Structure,_sequence_and_organization">structure, sequence, and organization</a>? The spec itself says,</p>

<blockquote>
  <p>Users of these documents should consult all applicable laws and regulations. <em>[…]</em> Implementers of the standard are responsible for observing or referring to the applicable regulatory requirements.</p>
</blockquote>

<p>So no help there. In short, I don’t know how to create FP bindings that conform to 754 without exposing myself to a copyright infringement lawsuit in the US from IEEE. Sigh.</p>

<p>My first suggestion is obvious, and should have been obvious all along: IEEE 754 should be made freely available. Maybe take some inspiration from <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA-262</a>?</p>

<p>That’s not all though, there are issues with the contents of the spec too.</p>

<h3 id="the-spec-is-too-specific">The spec is too specific</h3>
<p>The main problem with how the bindings are specified is that they’re <em>very</em> specific. Here’s an example (my bold),</p>

<blockquote>
  <p>This clause specifies <strong>five kinds of exceptions that shall be signaled</strong> when they arise; the signal invokes default or alternate handling for the signaled exception. <strong>For each kind of exception the implementation shall provide a corresponding status flag</strong>.</p>
</blockquote>

<p>What does it mean to provide a status flag? Is it like in JavaScript where the captures from the last regexp match is available through <code class="language-plaintext highlighter-rouge">RegExp</code>?</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">$</span> <span class="o">/</span><span class="p">.(.).</span><span class="o">/</span><span class="p">.</span><span class="nf">exec</span><span class="p">(</span><span class="dl">"</span><span class="s2">abc</span><span class="dl">"</span><span class="p">)</span>
<span class="c1">// &gt; ["abc", "b"]</span>
<span class="nx">$</span> <span class="nb">RegExp</span><span class="p">.</span><span class="nx">$1</span>
<span class="c1">// &gt; "b"</span>
</code></pre></div></div>

<p>It looks like that’s what it means, especially if you consider functions like <em>saveAllFlags</em>,</p>

<blockquote>
  <p>Implementations shall provide the following non-computational operations that act upon multiple status flags collectively: <em>[snip]</em></p>

  <p>― flags <strong>saveAllFlags</strong>(void)</p>

  <p>Returns a representation of the state of all status flags.</p>
</blockquote>

<p>This may have made sense at the time of the original spec in 1985 but it’s mutable global state – something that has long been recognized as problematic and which languages are increasingly moving away from.</p>

<p>Here’s another example. It sounds very abstract but for simplicity you can think of “attribute” as <em>roundingMode</em> and “constant value” as a concrete rounding mode, for instance <em>roundTowardsZero</em>.</p>

<blockquote>
  <p>An attribute is <strong>logically associated with a program block to modify its numerical and exception semantics</strong>. <em>[…] *For attribute specification, the implementation shall provide language-defined means, such as compiler directives, to specify a constant value for the attribute parameter for all standard operations in a block *[…].</em></p>
</blockquote>

<p>Program block? Attribute specification? Nothing else in my language works this way. How do I even apply this in practice? If attributes are lexically scoped then that would mean rounding modes only apply to code textually within the scope – if you call out to a function its operations will be unaffected. If on the other hand attributes are dynamically scoped then it works with the functions you call – but dynamically scoped state of this flavor is really uncommon these days, most likely nothing else in your language behaves this way.</p>

<p>You get the picture. The requirements are very specific and some of them are almost impossible to apply to a modern language. Even with the best will in the world I don’t know how to follow them except by embedding a little mini-language just for FP that is completely different in flavor from the rest. Surely that’s not what anyone wants?</p>

<h3 id="what-do-i-want-then">What do I want then?</h3>
<p>As I said earlier, it’s not that I want to be left alone to do FP myself. I’m a language guy, almost certainly I won’t get this right without guidance. So what is it that I want?</p>

<p>I want the <em>motivation</em>, not some solution. Give me a suggested solution if you want but please also tell me what the problem is you’re trying to solve, why I’m supporting this in the first place. That way, if for some reason your suggested solution just isn’t feasible there’s the possibility that I can design a more appropriate solution to the same problem. That way at least there’ll be <em>a</em> solution, just not the suggested one.</p>

<p>For instance, it is my understanding that the rounding mode mechanism was motivated mainly by the desire to have a clean way to determine error bounds. (<em>Note: as pointed out on <a href="https://news.ycombinator.com/item?id=8579061">HN</a> and in the comments, the rest of this section is wrong. Something similar was indeed the motivation for the mechanism but not exactly this, and you don’t get the guarantees I claim you do. See the HN discussion for details.</em>) It works like this. Say you have a nontrivial computation and you want to know not just a result but also the result’s accuracy. With the rounding mode model you’d do this: repeat the exact same computation three times, first with the default rounding, then round-positive (which is guaranteed to give a result no smaller than the exact result) and finally round-negative (which is guaranteed to give a result no larger). This will give you an approximate result and an interval that the exact result is guaranteed to be within. The attribute scope gymnastics are to ensure that you can replicate the computation exactly, the only difference being the rounding mode. It’s actually a pretty neat solution if your language can support it.</p>

<p>It’s also a use case that makes sense to me, it’s something I can work with and try to support in my own language. Actually, even if I can implement the suggested bindings exactly as they’re given in the spec the motivation is still useful background knowledge – maybe it’s a use case I’ll be extra careful to test.</p>

<p>I’m sure there are other uses for the binding modes as well. But even if I assume, wrongly, that there isn’t, that misapprehension is still an improvement over the current state where I have nothing to fall back to so I dismiss the whole rounding mode model outright.</p>

<p>(As a bitter side note, minutes from the 754-2008 revision meetings are <a href="http://www.validlab.com/754R">available</a> online and I expect they contain at least some of the motivation information I’m interested in. I don’t know though, I can’t search for the relevant parts because the site’s <a href="http://www.validlab.com/754R/robots.txt">robots.txt</a> prevents search engines from indexing them. Grr.)</p>

<p>In conclusion, I think the people who regret that languages don’t have proper support for 754 could do a lot to improve that situation. Specifically,</p>

<ol>
  <li>
    <p>Fix the licensing terms on the spec document.</p>
  </li>
  <li>
    <p>Describe the use cases you need support for, not just one very specific solution which is hard to apply to a modern language.</p>
  </li>
  <li>
    <p>As an absolute minimum, fix the <code class="language-plaintext highlighter-rouge">robots.txt</code> so the spec meeting minutes become searchable.</p>
  </li>
</ol>

<p>(<a href="https://news.ycombinator.com/item?id=8576837">HN discussion</a>, <a href="http://www.reddit.com/r/programming/comments/2lu9ey/why_i_find_ieee_754_frustrating/">reddit discussion</a>)</p>

<p>Update: removed sentence that assumed the spec’s concept of exceptions referred to try/except style exceptions. Don’t use the term “interval arithmetic” about determining error bounds.</p>]]></content><author><name>Christian Plesner Hansen</name></author><category term="languages" /><summary type="html"><![CDATA[Programming languages new (Java) and old (Fortran), and their compilers, still lack competent support for features of IEEE 754 so painstakingly provided by practically all hardware nowadays. […] Programmers seem unaware that IEEE 754 is a standard for their programming environment, not just for hardware. William Kahan]]></summary></entry></feed>