Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs

Dashboard
Notifications
Mark all as read
Challenges

Encode and decode floating point integers

+2
−0

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=E-1$ 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 code-golf, 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
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

2 answers

+2
−0

Haskell, 219 194 bytes

h!n=x n?(a?c$d>n&&(even a?f(<)$f(==)))$h where(a,b)=e!!(c-1);(c,d)=dropWhile((<n).snd)e!!0;f g=g(n*2)$b+d
x n=m?(2^(e-1)*(m+32))$e<1where(e,m)=divMod n 32
e=map((,).id<*>x)[0..]
(a?b)c|c=a|0<1=b

Try it online!

Depending on the first argument:

  • False - Encode
  • True - Decode
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+1
−0

Python 3, 268 250 235 233 210 197 148 bytes

def a(n):e=(n>>6).bit_length();f=2**e;l=n&(f-1);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))

Try it online!

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.

Why does this post require moderator attention?
You might want to add some details to your flag.

7 comment threads

148 bytes (1 comment)
163 bytes (1 comment)
180 bytes (1 comment)
188 chars (1 comment)
197 bytes (1 comment)
Show more

Sign up to answer this question »

This community is part of the Codidact network. We have other communities too — take a look!

You can also join us in chat!

Want to advertise this community? Use our templates!