Encode and decode floating point integers
Imagine you have only one byte (8 bits) to store a value, but need to store values from $0$ to $4032$. Impossible, until you are also told that an error of 1/64 of the exact value does not matter.
With that knowledge, you decide to design a floating point integer type, which is defined as follows:

All representable numbers are of the form $m\cdot 2^e$, where $m$ is the mantissa and $e$ is the exponent. There are no NaNs and no infinities.

The upper three bits of the byte are the exponent, the lower five are the mantissa. Since no negative numbers are stored, no sign bit is needed.
I'll refer to the three bit number represented by the exponent bits as $E$, and the 5 bit value represented by the mantissa bits as $M$

If $E=0$, then $e=0$ and $m=M$ (“denormalized integer”).

Otherwise, $e=E1$ and $m=M+32$
Your task is now to write code that converts a positive integer to that floating point format and back. In particular:

Encoding:

Your code takes an integer $0\le n\le 4032$, and outputs an integer $0\le r\le 255$. You can assume that the input integer is always in the allowed range (that is, no overflow handling is required)

If $n$ can be represented exactly, $r$ is the corresponding representation.

Otherwise, if $n$ is exactly in the middle of two consecutive exactly representable numbers, $r$ is the choice with the even mantissa.

Otherwise, $r$ is the representation of the closest exactly representable number.


Decoding:
Your code takes an integer $0\le r\le 255$ and outputs the integer $0\le n\le 4032$ it represents.
You can write either two separate routines for encoding and decoding, or a single routine that takes an extra argument telling whether to encode or decode. Here “routine” refers to any form of executable code taking input and giving output (program, function, macro, …).
This is codegolf, that is the shortest code wins. If you choose separate encoding and decoding routines, the score is the sum of the sizes of the encoding and decoding routines.
An ungolfed (and unoptimized) Python implementation is available here
Test cases:
Encoding:
input output
0 0
1 1
31 31
32 32
63 63
64 64
65 64
66 65
67 66
68 66
69 66
70 67
123 94
124 94
125 94
126 95
127 96
128 96
129 96
130 96
131 97
256 128
2021 223
4032 255
Decoding:
input output
0 0
1 1
31 31
32 32
63 63
64 64
65 66
66 68
93 122
94 124
95 126
96 128
97 132
128 256
160 512
223 2016
224 2048
255 4032
2 answers
Haskell, 219 194 bytes
h!n=x n?(a?c$d>n&&(even a?f(<)$f(==)))$h where(a,b)=e!!(c1);(c,d)=dropWhile((<n).snd)e!!0;f g=g(n*2)$b+d
x n=m?(2^(e1)*(m+32))$e<1where(e,m)=divMod n 32
e=map((,).id<*>x)[0..]
(a?b)cc=a0<1=b
Depending on the first argument:
 False  Encode
 True  Decode
0 comment threads
Python 3, 268 250 235 233 210 197 148 bytes
def a(n):e=(n>>6).bit_length();f=2**e;l=n&(f1);N=(n>>e)&31;return((e+(n>31))<<5)+N+(2*l+N%2>f)
def b(r):E=r>>5;return((r&31)+32*(E>0))*2**(E(E>0))
Golfed 15 bytes thanks to @celtschk's advice. Golfed another 23 bytes thanks to @celtschk's advice. Golfed another 13 bytes thanks to @celtschk's advice. Golfed another 49 bytes thanks to @celtschk's advice.
0 comment threads