`wip`
```2 files changed, 39 insertions(+), 38 deletions(-)

M episode10/cbor.go
```
`M episode10/README.md +38 -37`
```@@ 36,24 36,24 @@ one:
----

In the [previous episode][ep9] we added floating point number support to our
-encoder. We took care to minimize the size of the output by using small floats
-when appropriate. There’s still room for improvement: we encode regular
-floating point numbers efficiently, but there are also special numbers on the
-standard IEEE 754 that we haven’t dealt with yet and that can be packed most
-efficiently:
+encoder. We minimized the size of the output by using small floats when
+appropriate. While our encoder can encode any floating point number, we can
+minimize the out further: we encode regular floating point numbers efficiently,
+but we didn’t optimize special numbers. There are 3 types of special numbers
+from the standard IEEE 754 that we can packed more efficiently:

+- Infinities
+- Not a Number
- Subnumbers, also called denormal numbers, denormalized numbers, or subnormal
numbers. They includes 0 which can’t be encoded accurately as a regular
floating point number
-- Infinities
-- Not a Number

-The way the encoder works now these special values are all encoded as 64 bits
-floats, but most of them we can be encoded as 16 bits numbers without losing
+How the encoder works now these special values are all encoded as 64 bits
+floats. Most of them we can be encoded as 16 bits numbers without losing
information.

-We’ll starts with infinite values, then not a number values, and finish with the
-most challenging case: subnormal numbers.
+We’ll starts with infinite values, then ‘not a number’ values, and finish with
+the most challenging type: subnormal numbers.

There are too types of infinite values: positive and negative. Infinite values
are encoded with the sign bit, all 1’s in the exponent, and all 0’s for the

@@ 69,15 69,13 @@ 0’s in the fractional:
...
}

-Not a number or NaN is similar to infinites but with a non-zero fractional part.
-The fractional part of a NaN carries some information, we’ll copy as is and just
-chop off the end because all the important information is in the first few bits.
-We add the following the second switch statement:
+Not a number or NaN values are similar to infinites, but they have a non-zero
+fractional part. The fractional part of a NaN carries some information, we’ll
+copy as is and just chop off the end because all the important information is in
+the first few bits. We add the following the second switch statement:

func (e *Encoder) writeFloat(input float64) error {
-        if math.IsInf(input, 0) {
-            return e.writeFloat16(math.Signbit(input), (1<<float16ExpBits)-1, 0)
-        }
+        ...
var (
exp, frac     = unpackFloat64(input)
trailingZeros = bits.TrailingZeros64(frac)

@@ 91,30 89,27 @@ We add the following the second switch s
}
}

-And that’s all we need for not a number. We now store tightly infinites and not
-a number, now comes the hard part: subnormal numbers. There’s some bits fiddling
+The f variable in is the fractional part of the value that we shift by 48 bits
+to keep the first high bits when we convert it to a 10 bits fractional. That’s
+all we need for not a number, we store more tightly infinites and not a number
+values. Now comes the hard part: subnormal numbers. There’s some bits fiddling

-!!WIP!!
-
When a binary value of an exponent is all 0’s it means we have a subnormal
-number. Zero is a subnormal number. When the exponent’s binary value is all 1’s
-it means we have either an infinity number, or a “not a number” value.
+number. One important subnormal number is zero.

Zero is a special floating point value because it cannot be represented
precisely with the default formula where the fractional part is prefixed by a 1.
Even if the factional and exponent was very small it wouldn’t precisely by 0
because there’s always a 1 somewhere in here (like 0.000...01), so we have

[subnormal numbers]: https://en.wikipedia.org/wiki/Denormal_number

-To support this we’ll have to copy the sign bit from the original number.
-Let’s
-
Let’s start by encode efficiently zero and negative zero. Negative zero is a
-zero subnumber with its sign bit set to one. Here are the two test we add to our
-test suite:
+zero subnumber with its sign bit set to one. To support this we’ll have to copy
+the sign bit from the original number. Here are the two test we add to our test
+suite:

...
{Value: 0.0, Expected: []byte{0xf9, 0x00, 0x00}},

@@ 123,23 118,29 @@ test suite:

To get a negative zero in Go we have to use the math.Copysign function otherwise
the compiler turns the expression -0.0 into a positive zero. Zeros can be
-encoded as 16 bits floats. We add a if statement at the beginning of the
-writeFloat method and we’re done with zeros:
+encoded as 16 bits floats. We change the if statement at the beginning of the
+writeFloat method into a switch statement to deal with infinites and zeros
+together:

func (e *Encoder) writeFloat(input float64) error {
-        if input == 0 {
+        switch {
+        case input == 0:
return e.writeFloat16(math.Signbit(input), 0, 0)
+        case math.IsInf(input, 0):
+            return e.writeFloat16(math.Signbit(input), 1<<float16ExpBits-1, 0)
}
...
}

Note that we don’t check if the input equals -0.0 because -0.0 == 0.0.

-What about the other subnormal numbers? How we can represent them and use them
-to encode other numbers tigthly?
+!!WIP!!

-floating point numbers:
+We’ve done zero and what about the other subnormal numbers? How we can represent
+subnormal numbers. The main difference is with the formual where the fractional
+prefix is a 0 instead of a 1. Here’s the formula for regular floating point
+numbers:

> (−1)<sup>signbit</sup> × 2<sup>exponent−15</sup> × 1.significantbits<sub>2</sub>

```
`M episode10/cbor.go +1 -1`
```@@ 178,7 178,7 @@ func subnumber(exp int, zeros int) bool
}

func (e *Encoder) writeFloat(input float64) error {
-	// First check if we have a special value: 0, NaN, Inf, -Inf
+	// First check if we have a special value: 0, Inf, -Inf
switch {
case input == 0:
return e.writeFloat16(math.Signbit(input), 0, 0)

```