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

M episode10/README.md
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
 ahead.
 
-!!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][] that start with a 0 instead of a 1.
+[subnormal numbers][] that start with a 0 instead of a 1 to address this.
 
 [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!!
 
-First let’s learn more about subnormal numbers. Here’s the formula for regular
-floating point numbers:
+We’ve done zero and what about the other subnormal numbers? How we can represent
+them and use them to encode other numbers tigthly? Let’s learn more about
+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)