user
**Posit** is a quantization of the real projective line proposed by John Gustafson in 2015. It is claimed to be an improvement over IEEE 754.

The purpose of this task is to write a program capable of decoding a posit number. You will use the example provided by Gustafson in his paper : 0b0000110111011101, representing a 16-bit long real number with three bits for the exponent. Once decoded, you should obtain either the fraction 477/134217728 or the floating point value 3.55393E−6.

Jeff Johnson from Facebook research, described posit numbers as such:

:   A more efficient representation for tapered floating points is the recent *posit* format by Gustafson. It has no explicit size field; the exponent is encoded using a Golomb-Rice prefix-free code, with the exponent 

    e
    {\displaystyle {\displaystyle e}}
     encoded as a Golomb-Rice quotient and remainder 

    (
    q
    ,
    r
    )
    {\displaystyle {\displaystyle (q,r)}}
     with 

    q
    {\displaystyle {\displaystyle q}}
     in unary and 

    r
    {\displaystyle {\displaystyle r}}
     in binary (in posit terminology, 

    q
    {\displaystyle {\displaystyle q}}
     is the *regime*). Remainder encoding size is defined by the *exponent scale* 

    s
    {\displaystyle {\displaystyle s}}
    , where 

    2

    s
    {\displaystyle {\displaystyle 2^{s}}}
     is the Golomb-Rice divisor. Any space not used by the exponent encoding is used by the significand, which unlike IEEE 754 always has a leading 1; gradual underflow (and overflow) is handled by tapering. A posit number system is characterized by 

    (
    N
    ,
    s
    )
    {\displaystyle {\displaystyle (N,s)}}
    , where 

    N
    {\displaystyle {\displaystyle N}}
     is the word length in bits and 

    s
    {\displaystyle {\displaystyle s}}
     is the exponent scale. The minimum and maximum positive finite numbers in 

    (
    N
    ,
    s
    )
    {\displaystyle {\displaystyle (N,s)}}
     are **Failed to parse (syntax error): {\displaystyle f\_\mathrm{min} = 2^{−(N−2)2^s}}**
    and **Failed to parse (syntax error): {\displaystyle f\_\mathrm{max} = 2^{(N−2)2^s}}**
    . The number line is represented much as the projective reals, with a single point at 

    ±
    ∞
    {\displaystyle {\displaystyle \pm \infty }}
     bounding **Failed to parse (SVG (MathML can be enabled via browser plugin): Invalid response ("Math extension cannot connect to Restbase.") from server "https://wikimedia.org/api/rest\_v1/":): {\displaystyle −f\_\mathrm{max}}**
    and 

    f


    m
    a
    x
    {\displaystyle {\displaystyle f\_{\mathrm {max} }}}
    . 

    ±
    ∞
    {\displaystyle {\displaystyle \pm \infty }}
     and 0 have special encodings; there is no NaN. The number system allows any choice of 

    N
    ≥
    3
    {\displaystyle {\displaystyle N\geq 3}}
     and **Failed to parse (syntax error): {\displaystyle 0\le s\le N − 3}**
    .
:   s
    {\displaystyle {\displaystyle s}}
     controls the dynamic range achievable; e.g., 8-bit (8, 5)-posit 

    f


    m
    a
    x
    =

    2

    192
    {\displaystyle {\displaystyle f\_{\mathrm {max} }=2^{192}}}
     is larger than 

    f


    m
    a
    x
    {\displaystyle {\displaystyle f\_{\mathrm {max} }}}
     in float32. (8, 0) and (8, 1) are more reasonable values to choose for 8-bit floating point representations, with 

    f


    m
    a
    x
    {\displaystyle {\displaystyle f\_{\mathrm {max} }}}
     of 64 and 4096 accordingly. Precision is maximized in the range **Failed to parse (syntax error): {\displaystyle \pm\left[2^{−(s+1)}, 2^{s+1}\right)}**
    with **Failed to parse (syntax error): {\displaystyle N − 3 − s}**
    significand fraction bits, tapering to no fraction bits at 

    ±

    f


    m
    a
    x
    {\displaystyle {\displaystyle \pm f\_{\mathrm {max} }}}
    .
:   — Jeff Johnson, *Rethinking floating point for deep learning*, Facebook research.
assistant
**Translation of**: Mathematica

```
=begin LICENSE
Copyright © 2017 John L. Gustafson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub-license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

This copyright and permission notice shall be included in all copies or substantial portions of the software.

THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY,
WHETHER IN AN ACTION OR CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=end LICENSE

constant nbits = 16;
constant es    = 3;
constant npat  = 2**nbits;
constant useed = 2**2**es;
constant minpos = useed**(-nbits + 2);
constant maxpos = useed**(+nbits - 2);
constant qsize  = 2**((nbits-2)*2**(es+2)+5).log2.ceiling;
constant qextra = qsize - (nbits - 2)*2**(es+2);

constant posit-range = 0..^2**nbits;

sub twoscomp($sign, $p) { ($sign > 0 ?? $p !! npat - $p) mod npat } 

sub sign-bit(UInt $p where posit-range) { +$p.polymod(2 xx nbits - 1).tail }
sub regime-bits(UInt $p where posit-range) {
  my $q = twoscomp(1 - sign-bit($p), $p);
  my @bits = $q.polymod(2 xx nbits - 1).reverse;
  my $bit2 = @bits[1];
  my @temp-bits = flat @bits[1..*], 1 - $bit2;
  my $npower = @temp-bits.first(1 - $bit2, :k) - 1;
  @bits[1..($npower+1)];
}
sub regime-value(@bits) { @bits.head ?? @bits.elems - 1 !! -@bits; }
sub exponent-bits(UInt $p where posit-range) {
  my $q = twoscomp(1 - sign-bit($p), $p);
  my $startbit = regime-bits($q).elems + 3;
  my @bits = $q.polymod(2 xx nbits - 1).reverse;
  @bits[$startbit-1 .. $startbit-1 + es - 1]
}
sub fraction-bits(UInt $p where posit-range) {
  my $q = twoscomp(1 - sign-bit($p), $p);
  my $startbit = regime-bits($q).elems + 3 + es;
  my @bits = $q.polymod(2 xx nbits - 1).reverse;
  @bits[$startbit-1 .. *];
}

sub p2x(UInt $p where posit-range) {
  my $s = (-1)**sign-bit($p);
  my $k = regime-value regime-bits $p;
  my @e = exponent-bits $p;
  my @f = fraction-bits $p;
  @e.push: 0 until @e == es;
  my $e = @e.reduce: 2 * * + *;
  my $f = @f == 0 ?? 1 !! 1.FatRat + @f.reduce(2 * * + *)/2**@f;
  given $p {
    when 0          { 0   }
    when npat div 2 { Inf }
    default         { $s * useed**$k * 2**$e * $f }
  }
}

dd p2x 0b0000110111011101;

```

Output:

```
FatRat.new(477, 134217728)
```

You may Attempt This Online!