|
84 | 84 | </span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#0000cf;font-weight:700>11111111</span> <span style=color:#0000cf;font-weight:700>11111111</span> <span style=color:#0000cf;font-weight:700>11111111</span> <span style=color:#0000cf;font-weight:700>11111111</span> <span style=color:#0000cf;font-weight:700>00000001</span><span style=color:#a40000> |
85 | 85 | </span></span></span></code></pre></div><p>This is the <em>two’s complement</em> of 2, defined in unsigned arithmetic as <code>~0 - 2 + 1</code>, where <code>~0</code> is the all-ones 64-bit integer. It is a useful exercise to |
86 | 86 | understand why this produces so many ones.</p><p><code>sintN</code> uses the “ZigZag” encoding instead of two’s complement to encode |
87 | | -negative integers. Positive integers <code>n</code> are encoded as <code>2 * n</code> (the even |
88 | | -numbers), while negative integers <code>-n</code> are encoded as <code>2 * n + 1</code> (the odd |
| 87 | +negative integers. Positive integers <code>p</code> are encoded as <code>2 * p</code> (the even |
| 88 | +numbers), while negative integers <code>n</code> are encoded as <code>2 * |n| - 1</code> (the odd |
89 | 89 | numbers). The encoding thus “zig-zags” between positive and negative numbers. |
90 | 90 | For example:</p><table><thead><tr><th>Signed Original</th><th>Encoded As</th></tr></thead><tbody><tr><td>0</td><td>0</td></tr><tr><td>-1</td><td>1</td></tr><tr><td>1</td><td>2</td></tr><tr><td>-2</td><td>3</td></tr><tr><td>…</td><td>…</td></tr><tr><td>0x7fffffff</td><td>0xfffffffe</td></tr><tr><td>-0x80000000</td><td>0xffffffff</td></tr></tbody></table><p>Using some bit tricks, it’s cheap to convert <code>n</code> into its ZigZag representation:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-fallback data-lang=fallback><span style=display:flex><span>((n + n) ^ -(n < 0)) - (n < 0) |
91 | 91 | </span></span></code></pre></div><p>Here, we assume that the boolean <code>n < 0</code> is converted into an integer 1 if true |
92 | 92 | or an integer 0 if false.</p><p>When the <code>sint32</code> or <code>sint64</code> is parsed, its value is decoded back to the |
93 | 93 | original, signed version.</p><p>In protoscope, suffixing an integer with a <code>z</code> will make it encode as ZigZag. |
94 | | -For example, <code>-500z</code> is the same as the varint <code>1001</code>.</p><h3 id=non-varint-numbers>Non-varint Numbers</h3><p>Non-varint numeric types are simple – <code>double</code> and <code>fixed64</code> have wire type |
| 94 | +For example, <code>-500z</code> is the same as the varint <code>999</code>.</p><h3 id=non-varint-numbers>Non-varint Numbers</h3><p>Non-varint numeric types are simple – <code>double</code> and <code>fixed64</code> have wire type |
95 | 95 | <code>I64</code>, which tells the parser to expect a fixed eight-byte lump of data. We can |
96 | 96 | specify a <code>double</code> record by writing <code>5: 25.4</code>, or a <code>fixed64</code> record with <code>6: 200i64</code>. In both cases, omitting an explicit wire type infers the <code>I64</code> wire |
97 | 97 | type.</p><p>Similarly <code>float</code> and <code>fixed32</code> have wire type <code>I32</code>, which tells it to expect |
|
0 commit comments