24
\$\begingroup\$

Had my software final exams recently, one of the last questions had me thinking for a while after the exam had finished.

Background

IEEE754 numbers are according to the below layout Layout for a 32 bit floating point number

The exponent is stored as n + 127 so for an exponent of 20 the exponent in binary would be: 127 + 20 = 147 then 10010011

The Challange

Write a program that when given text representing a binary floating point number to the IEEE754 standard, returns the exponent given as a decimal value.

Example

Input: 00111101110011001100110011001101 (0.1)

Isolated exponent bits: 01111011

Convert to binary: 0 + 64 + 32 + 16 + 8 + 0 + 2 + 1 = 123

Remove offset: 123 - 127 = -4

Output -4


Input: 10111111110111101011100001010010 (-1.64)

Isolated exponent bits: 01111111

Convert to binary: 0 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 127

Remove offset: 127 - 127 = 0

Output 0

Rules

  • Input must be text/string/equivalent indexable datatype, eg. strings not integer or numerical
  • Output can be any type, as long as it is decimal
  • Aim for shortest solutions

Adapted from the 2020 Software Design and Development HSC Paper: 30) d) ii

Design an algorithm that takes in a string of 32 characters representing a floating point number, and displays the exponent as its signed decimal value.

Any feedback is appreciated as this is my first question

\$\endgroup\$
17
  • 1
    \$\begingroup\$ Can we take the input as a list of 1s and 0s? \$\endgroup\$
    – Adám
    Nov 5, 2020 at 9:50
  • 1
    \$\begingroup\$ All challenges here must have an objective scoring criterion, for which we usually recommend code-golf unless you have something else in mind. \$\endgroup\$
    – Bubbler
    Nov 5, 2020 at 9:50
  • 1
    \$\begingroup\$ Also, if you have another challenge idea, please use the sandbox to gather feedback from other users and fix potential problems. It is recommended to leave a challenge there for at least 3 days before posting it to main. \$\endgroup\$
    – Bubbler
    Nov 5, 2020 at 10:03
  • 1
    \$\begingroup\$ Btw, welcome to the site! Nice first challenge. In the future, consider using the Sandbox. Had it been there, I might have suggested taking a variable length input representing a binary float with 16/32/64/128/265 bits. \$\endgroup\$
    – Adám
    Nov 5, 2020 at 10:05
  • 6
    \$\begingroup\$ @Adám I would of submitted it there but was unable to as i have less than 5 reputation \$\endgroup\$ Nov 5, 2020 at 10:25

37 Answers 37

8
\$\begingroup\$

Haskell, 33 bytes

foldl1(\x y->x*2+y-1).take 8.tail

Try it online!

Input is a list of integers 0 or 1.

It's slightly shorter to foldl1 by x*2+y-1 than to subtract 127 at the end. This works because

  foldl1 (\x y->x*2+y-1) [a,b,c,d,e,f,g,h]
= ((((((a*2+b-1)*2+c-1)*2+d-1)*2+e-1)*2+f-1)*2+g-1)*2+h-1
= a*128 + b*64-64 + c*32-32 + d*16-16 + e*8-8 + f*4-4 + g*2-2 + h-1
= 128a + 64b + 32c + 16d + 8e + 4f + 2g + h - 127
= fromBinary[a,b,c,d,e,f,g,h]-127
\$\endgroup\$
8
\$\begingroup\$

Python 3, 26 bytes

lambda s:int(s[1:9],2)-127

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ How dare you beat me by 5 seconds with the exact same code! \$\endgroup\$
    – pxeger
    Nov 5, 2020 at 10:04
  • 6
    \$\begingroup\$ @pxeger I wrote a full test suite so as not to rush you! :D \$\endgroup\$
    – Noodle9
    Nov 5, 2020 at 10:05
8
\$\begingroup\$

C (gcc), 55 \$\cdots\$ 40 36 bytes

Saved 2 6 bytes thanks to ceilingcat!!!
Saved 2 a whopping 13 bytes thanks to Arnauld!!!

#define f(s)strtol(s+1,s[9]=0,2)-127

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ The built-in approach. \$\endgroup\$
    – Arnauld
    Nov 5, 2020 at 12:13
  • \$\begingroup\$ @Arnauld Had to tweek it a bit to get it working for other testcases and saved another byte! Great idea - thanks! :D \$\endgroup\$
    – Noodle9
    Nov 5, 2020 at 13:58
6
\$\begingroup\$

05AB1E, 8 7 bytes

¦8£CƵQ-

Try it online!

¦8£CƵQ-
¦             remove first element
 8£           take next 8 elements
   C          convert from binary string to an integer
    ƵQ        push 127
      -       subtract

Thanks to Kevin for -1 byte

\$\endgroup\$
3
6
\$\begingroup\$

x86 machine code, 14 bytes

Same machine code works in 32 or 64-bit mode. (Same length for 16-bit mode would be easy with different regs). Callable from C as x86-64 System V int8_t getexp(const char *b2_str);

    23        ; input: char *str in RDI
    24        ; return: int8_t AL; (calling convention allows garbage in high bytes of RAX)
    25                         getexp_scalar:
    26 00000030 6A09              push 9                 ; sign bit gets shifted out the top.
    27 00000032 59                pop  rcx
    28 00000033 B030              mov  al, '0'
    29                         .loop:
    30 00000035 AE                 scasb                    ; set FLAGS like cmp '0', [rdi]  would, if it was encodeable
    31 00000036 10D2               adc  dl,dl               ; DL = DL<<1 | CF, rotate CF into DL.
    32 00000038 E2FB              loop .loop
    33 0000003A 8D4281            lea  eax, [rdx-127]      ; no shorter than sub dl, 127  or  xchg eax,edx / sub al,127
    34 0000003D C3                ret

We just do base 2 ASCII->integer conversion for 9 bits, letting the first bit (sign bit) overflow off the top of DL. The 8-bit return value is only the 8-bit AL register, as a 2's complement binary integer.

adc dl,dl to rotate CF into DL is more efficient on modern CPUs than rcl dl, 1 (rotate through carry, i.e. shift in CF). They're equivalent except for some FLAGS output semantics. I could have used EDX for the same code size; that would simply leave different garbage in the high bytes outside the AL return value in RAX. (And yes, high garbage above narrow return values is 100% allowed by standard x86 calling conventions.)

Try it online! 3 versions with a test caller.
(Including alternate 15-byte scalar version using lodsb / and al, 1 / lea edx, [rdx*2 + rax])

x86-64 SIMD (MMXext+MOVBE) machine code, 20 bytes

Having base-2 digits in MSB-first printing order is a major inconvenience for little-endian x86, where the lowest SIMD vector element comes from the lowest address in memory. x86 lacks a bit-reverse like ARM's rbit, so I used x86-64 features to byte-reverse 8 bytes. Without that, movq mm0, [e/rdi+1] (4B) / pslld mm0,7 (4B) would be 32-bit-mode compatible and work on a Pentium III (pmovmskb r32, mm was new with SSE, aka MMXext, so not original P5 Pentium-MMX).

                             ; input: char *RDI;   result int8_t AL
                             ; clobbers: MM0.  Leaves FPU in MMX state (no EMMS)
    12                         getexp_mmx:
    14 00000010 480F38F04701          movbe    rax, [rdi+1]   ; byte-reverse (big-endian) load of the exponent field.  saves 1B vs. mov + bswap
    15 00000016 48C1E007              shl      rax, 7         ; low bit to high in each byte.  same size as pslld mm0, 7.
    16 0000001A 480F6EC0              movq     mm0, rax
    17 0000001E 0FD7C0                pmovmskb eax, mm0       ; pack vector high bits into 1 byte
    18 00000021 2C7F                  sub      al, 127
    19 00000023 C3                    ret
; size = 0x24 - 0x10 = 0x14 = 20 B

MMX instructions typically need 1 fewer prefix byte than SSE2 and later; if you were doing this for real you'd probably use XMM0, and avoid the EMMS (exit MMX state) that real code would normally use. (And maybe a pshufb for the byte reverse if you have SSSE3, to avoid bouncing through integer regs...) This should still be much faster than a loop with adc and false dependencies, and the slow loop instruction itself. It's handy that the exponent field is exactly 8 bits wide. Doing this for double would need an SSE2 16-byte load (or 2 byte reverses and annoying shuffles to combine into a 16-byte vector), and would have to mask away the sign bit.

lodsb (1) + lodsq (2) + bswap rax (3) is the same total length as movbe rax, [rsi+1] (6), although that would make this portable to machines without movbe (Atom, Haswell and later).


For subnormal (aka denormal) floats including 0.0, this just returns -127, the unbiased the exponent field, as requested by the question. And -128 (overflowed from +128) for Inf / NaN inputs. (I only realized this overflow issue after the fact, posting anyway because all 255 possible outputs are unique, and that puts both special exponents at adjacent values so the caller can test for subnormal or inf/nan with e <= -127.)

It doesn't return the actual floor(log2(|x|)) of the represented value like AVX512 vgetexpps xmm, xmm does: (-Inf for an input of 0, and values below -127 for non-zero subnormals, matching the pseudocode in the documentation).

So even if we could take input as an actual binary floating-pointer number in IEEE754 binary32 format (aka float) in an XMM register, we couldn't just use that one 6-byte AVX512 instruction to produce an integer-valued float result.


not competing AVX2 version, 15 bytes

This takes its arg as 32 bytes of ASCII digits in a YMM register, but they have to be in least-significant-digit first order, hence not competing.

     2                         getexp_avx2_ymm_reversed:
     3             ; input: LSD-first ASCII digits in ymm0.  Probably can't justify that and would need to byte-reverse 
     5 00000000 C5FD72F007             vpslld     ymm0, ymm0, 7
     6 00000005 C5FDD7C0               vpmovmskb  eax, ymm0
     7 00000009 C1E817                 shr        eax, 23         ; AL = exponent
     8 0000000C 2C7F                   sub        al, 127
     9 0000000E C3                     ret

Fun fact: AVX-512 allows vpslld ymm0, [rdi], 7, if you had bytes in the LSD-first order in memory. (7 bytes including 4-byte EVEX, so an extra 2 bytes to take a char* instead of YMM arg.)

\$\endgroup\$
5
\$\begingroup\$

MathGolf, 7 bytes

╞8<å♣(-

Try it online.

Explanation:

╞        # Remove the first character of the (implicit) input-string
 8<      # Slice to only keep the first 8 characters of the string
   å     # Convert it from a binary-string to a base-10 integer
    ♣    # Push constant 128
     (   # Decrease it by 1 to 127
      -  # Subtract it from the integer
         # (after which the entire stack joined together is output implicitly as result)
\$\endgroup\$
5
\$\begingroup\$

JavaScript (ES6), 23 bytes

f=
b=>(`0b${b}0`>>>24)-127
<input oninput=o.textContent=f(this.value)><pre id=o>

Uses the fact that >>> truncates to 32 bits.

\$\endgroup\$
5
\$\begingroup\$

Ruby -n, 24 23 20 bytes

-1 byte thanks to Sisyphus
-3 bytes using -n command-line flag, inspired by this answer

p$_[1,8].to_i(2)-127

Try it online!

\$\endgroup\$
0
4
\$\begingroup\$

Kotlin,  26   31  29 bytes

Converted to a valid anonymous function, thanks to Bubbler
-2 bytes thanks to user

{it.slice(1..8).toInt(2)-127}

Try it online!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ s is not defined here. You can do s=>s.slice or {it.slice instead \$\endgroup\$
    – user
    Nov 5, 2020 at 18:17
  • \$\begingroup\$ @user - s is defined, and it's working! Any errors on your side? \$\endgroup\$
    – vrintle
    Nov 6, 2020 at 3:08
  • 1
    \$\begingroup\$ You need to include the part that defines s to be a function parameter in the byte count. Otherwise it is invalid. \$\endgroup\$
    – Bubbler
    Nov 6, 2020 at 4:34
  • 1
    \$\begingroup\$ This is a valid lambda function. \$\endgroup\$
    – Bubbler
    Nov 6, 2020 at 6:43
  • 2
    \$\begingroup\$ As user mentioned, this also works, where it is an implicit single parameter of a lambda. \$\endgroup\$
    – Bubbler
    Nov 6, 2020 at 8:01
4
\$\begingroup\$

Bash, 22 bytes

echo $[2#${1:1:8}-127]

Try it online!

Bash, 37 27 bytes

Input is from STDIN, output is to STDOUT.

expr $[2#`cut -b2-9`] - 127

Try it online!

Explanation

expr                             # Evaluate the following:

         `cut -b2-9`             #     Slice all characters from the 2nd character
                                 #     to the 9th character in standard input

     $[2#           ]            #     Convert it from base 2
                      - 127      #     And subtract by 127
\$\endgroup\$
2
  • 2
    \$\begingroup\$ welcome, new contributor! ~~oh wait~~ \$\endgroup\$
    – Razetime
    Nov 15, 2020 at 4:46
  • \$\begingroup\$ 22 bytes. \$\endgroup\$
    – roblogic
    Nov 30, 2020 at 11:27
4
\$\begingroup\$

Desmos, 42+9=51 40+9=49 30 bytes

f(l)=\sum_{i=0}^7l[9-i]2^i-127

Input as a list of 1's and 0's.

Try It On Desmos!

\$\endgroup\$
3
  • \$\begingroup\$ Always love Desmos creations! Nice \$\endgroup\$ Nov 14, 2020 at 12:59
  • \$\begingroup\$ @MaximilianRose Thanks! I spend quite a lot of time using Desmos so I thought I would just try my skills at code golf using Desmos. \$\endgroup\$
    – Aiden Chow
    Nov 15, 2020 at 2:56
  • \$\begingroup\$ I use to spend a lot of time on desmos, that's cool. Never even thought about shortcuts like "total" before. \$\endgroup\$
    – branboyer
    Dec 4, 2020 at 2:27
3
\$\begingroup\$

APL (Dyalog Unicode), 12 bytes (SBCS)

¯127+2⊥8↑1↓⊢

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Retina 0.8.2, 63 bytes

2=M&!`.{8}
1
01
+`10
011
$
-127$*
(1*)-\1
-
^0*(-)?(1*)-?
$1$.2

Try it online! Explanation:

2=M&!`.{8}

Get the second overlapping 8-character substring.

1
01
+`10
011

Convert to binary (may leave leading 0s).

$
-127$*
(1*)-\1
-

Subtract 127 (may leave trailing -).

^0*(-)?(1*)-?
$1$.2

Convert to decimal, removing garbage.

\$\endgroup\$
3
\$\begingroup\$

J, 12 bytes

127-~1{8#.\]

Try it online!

        #.        convert to binary
       8  \       all the infixes with length 8
           ]      of the argument
     1{           take the second one (0-indexed) 
127-~             subtract 127
        
\$\endgroup\$
3
\$\begingroup\$

C#, 120 115 42 32 bytes

s=>Convert.ToByte(s[1..9],2)-127

Thanks to @SunnyMoon for realising that the code is not actually 120 bytes (-2)
Thanks to @Sunnymoon for slaying 3 sneaky spaces in the code (-3)
Thanks to @user for coding a much much shorter lambda solution (-73)
Thanks to @thedefault. for using the .. operator and Convert.ToByte (-10)

Try it online!

As it turns out, C# is actually quite useful for golfing! Lambdas are the way to go!


Welcome to code golf, Maximilian Rose!

\$\endgroup\$
8
  • 2
    \$\begingroup\$ C# does lambdas, right? That would save on all the I/O overhead at least. \$\endgroup\$
    – Neil
    Nov 5, 2020 at 16:04
  • 2
    \$\begingroup\$ You can actually substantially decrease it using lambdas (42 bytes). You also had a few spaces here and there. \$\endgroup\$
    – user
    Nov 5, 2020 at 17:20
  • 2
    \$\begingroup\$ Well, you're now beating Retina... \$\endgroup\$
    – Neil
    Nov 5, 2020 at 20:27
  • 2
    \$\begingroup\$ 33 bytes by changing the compiler and using a range: Try it online!. I also think you can use Convert.ToByte instead of Convert.ToInt32. \$\endgroup\$ Nov 6, 2020 at 5:04
  • 2
    \$\begingroup\$ Thanks for the welcome \$\endgroup\$ Nov 10, 2020 at 6:19
3
\$\begingroup\$

Python 3, 54 bytes

ty to @Bubbler and @Kevin Cruijssen for corrections

lambda n: sum([2**i*int(n[8-i])for i in range(8)])-127

Try it online!

\$\endgroup\$
5
  • 6
    \$\begingroup\$ Answers must be a function (taking input from function parameter) or a full program (taking input from stdin), i.e. you can't assume that the input is already stored in a variable. You can convert it to an anonymous lambda instead. \$\endgroup\$
    – Bubbler
    Nov 5, 2020 at 9:57
  • 4
    \$\begingroup\$ I generally recommend waiting a week before answering your own challenge, especially if you do so in a popular language like Python. This is to give others a chance to discover and think about the task. You obviously know the game is on, and you've already spent time thinking about it. \$\endgroup\$
    – Adám
    Nov 5, 2020 at 9:59
  • \$\begingroup\$ You can remove the space at )for and the 0, in the range(8) (after converting it to a valid lambda as mentioned by @Bubbler). \$\endgroup\$ Nov 5, 2020 at 13:53
  • \$\begingroup\$ @Adám That's a big meh. You can just ignore the answer. Having an answer doesn't stop anyone from thinking about the task. To me, that type of policing goes far beyond the spirit of Stack Exchange. \$\endgroup\$ Nov 7, 2020 at 12:06
  • 1
    \$\begingroup\$ @Cody Gray and anyway I was so caught up with converting the solution I used in the actual exam which was psudocode without base conversion functions that I completely forgot about int(n, 2) to change base, which let another person find a shorter solution, I won't remove this one because I'm still proud of finding a nice use of list comprehension but I didn't expect it to be upvoted to the top of anything \$\endgroup\$ Nov 7, 2020 at 12:09
3
\$\begingroup\$

><>, 30 bytes

r~8[01:@{2%*+$2*60l4)?.{""-n;

(contains an unprintable DEL between the quotes)

Try it Online!

r~8[                           grab relevant part of string
    01                         accumulator and exponent initialization
                             main loop
       @{2%                    convert current digit charcter to 0 and 1
           *+$                 accumulate     
      :       2*               increment exponent
                60l4)?.        loop while digits remaining
                       {""-n;  print result sub 127 and terminate

Most of the work is constructing a number from binary notation.

\$\endgroup\$
3
\$\begingroup\$

Scala, 27 bytes

Uses Lynn's clever approach

_.slice(1,9)reduce(_*2+_-1)

Try it online

Scala, 29 bytes

n=>BigInt(n.slice(1,9),2)-127

Try it online!

Very straightforward. Takes a String, parses the exponent's bits as an integer in binary, then subtracts 127, returning a BigInt.

Scala, 29 bytes

n=>(BigInt(n.tail,2)>>23)-127

Try it online

Unfortunately, because of operator precedence, the outer parentheses are needed.

Scala, 29 bytes

_.slice(1,9)./:(0)(_*2+_)-127

Try it online

Yet another solution, this time taking a list of digits (List[Int]).

\$\endgroup\$
3
+50
\$\begingroup\$

Forth (gforth), 49 bytes

: b drop 1+ 8 ['] evaluate 2 base-execute 127 - ;

Try it online!

Done using (a lot of) Bubbler's help.

Forth has one(1) convenient command that allows interpretation of strings as binary, and that's used here(base-execute).

\$\endgroup\$
3
\$\begingroup\$

Rust, 43 bytes

|s|Ok(i32::from_str_radix(&s[1..9],2)?-127)

Try it online!

Returns a Result<i32,ParseIntError>. I would have loved to use an i8 instead of an i32 but that would panic if the leading bit is 1.

\$\endgroup\$
6
  • \$\begingroup\$ Is there no u8 type? \$\endgroup\$
    – Neil
    Nov 22, 2020 at 16:46
  • \$\begingroup\$ @Neil there is an i8 type but the code will panic if s[1] == 1 \$\endgroup\$
    – Aiden4
    Nov 22, 2020 at 20:14
  • \$\begingroup\$ ... I didn't ask about i8? \$\endgroup\$
    – Neil
    Nov 22, 2020 at 21:04
  • \$\begingroup\$ @Neil There is a u8 type but I would have to cast it into a different type to prevent underflow if s[1] == 0, and casts are lots of bytes \$\endgroup\$
    – Aiden4
    Nov 23, 2020 at 1:50
  • \$\begingroup\$ Oh, right, it will try to do an unsigned subtraction? I guess I'm too used to C's default int promotion. Sorry about that. \$\endgroup\$
    – Neil
    Nov 23, 2020 at 10:30
3
\$\begingroup\$

brainfuck, 174 113 111 bytes

-61 bytes for many optimizations

-2 bytes thanks to RezNesX

,>++++++++>>--[>-<--]>-<<<[>,>>>[--<+>]<[->+<]<-[<->-----]<+++[->>>[->+>+<<]>>[-<<+>>]<<<<<]<-]>>>>---[>-<--]>.

Try it online!

Input is 32 bits taken one at a time.

Explanation:

,> first bit garbage
++++++++ set cur cell (cell 2) to 8
>>--[>-<--]>-<<< set cell 5 to 128 (so the first division moves it over)

[> do 8 times

, input to cell 3

>>> cell 6
[--<+>] div 2 to 5
<[->+<] move back to 6
< cell 4

-[<->-----]<+++ convert to bin value (sub 48) using cell 4

[- if 1 (in cell 3)
>>>[->+>+<<] add cell 6 into cell 7 & 8
>>[-<<+>>] move cell 8 back to 6
<<<<<
]

<-] ends on c2

>>>> to c6 (has 1 and next cell has value)

---[>-<--]> sub 127
. outputs final answer (as ASCII= if this is invalid let me know)
\$\endgroup\$
1
3
\$\begingroup\$

Vyxal, 11 6 bytes

9ŻB⁺ɽ-

Try it Online!

I've got an advantage that y'all don't have: I actually sat the exam this question is based upon as well at the same time as the OP (#hsc_gang #option_topic_2 #ir_sw_hw). Hopefully I got both that question and this answer right!

Explained

9ŻB⁺ɽ-
9Ż      #     input[1:9]
  B     # int(          , 2)
   ⁺ɽ   #                      127 (N.B. Pushes the index of ɽ in the codepage + 101)
     -  #                    -
        # int(input[1:9], 2) - 127

Update: Turns out I got the wrong answer in the exam. Not pog.

\$\endgroup\$
4
  • \$\begingroup\$ finally, a challenge where Vyxal doesn't smash everything in \$\endgroup\$
    – Razetime
    Nov 15, 2020 at 3:35
  • \$\begingroup\$ No tail operator or prefix slicing!? (Or, a built-in for 127.) \$\endgroup\$
    – user99151
    Nov 15, 2020 at 4:14
  • \$\begingroup\$ @Razetime what were you saying? \$\endgroup\$
    – lyxal
    Nov 15, 2020 at 5:06
  • \$\begingroup\$ b r u h m o m e n t o \$\endgroup\$
    – Razetime
    Nov 15, 2020 at 5:12
2
\$\begingroup\$

Jelly, 8 bytes

Ḋḣ8Ḅ_127

Try it online!

Takes input as a list of digits

How it works

Ḋḣ8Ḅ_127 - Main link. Takes a list of bits B on the left
Ḋ        - Dequeue; Remove the first element of B
 ḣ8      - Take the first 8 elements
   Ḅ     - Convert from binary
    _127 - Subtract 127
\$\endgroup\$
2
\$\begingroup\$

K (ngn/k), 11 bytes

-127+2/8#1_

Try it online!

         1_        drop one
       8#          take 8
     2/            to binary
-127+              subtract 127

K (ngn/k), 14 bytes

Just an experiment - a port of Lynn's Haskell answer

{y-1+2*x}/8#1_

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Befunge-98 (PyFunge), 31 bytes

[email protected]~'$$<
_1->\2*~2%+\#^:!

Try it online!


Animation

enter image description here

Explanation

~$7v is the initialization code:
~$ read and discard the first character
7 push initial value of the loop counter
v redirect the instruction pointer down

The second line is the main loop, since > is the entry point it is executed as \2*~2%+\#^:!_1- from left to right. Initially the loop counter is on top of the stack and the current result on the second position:
\ swap to the current exponent value
2* double it
~ read the next digits
2% modulo 2 maps '0' to 0 and '1' to 1
+ add to the current result
\ swap to the loop counter
# skips the the command (^)
:! duplicate the loop counter and boolean negate the copy

If the value on the top of the stack is now falsey (loop counter was >0), _ lets the IP move east and the main loop continues by subtracing 1 from the loop counter (1-). Otherwise the IP moves west and executes the following:

    @.-1-~'$$<
_            ^:!

By removing the IP movement commands and writing everything from left to right, this results in !:$$'~-1-.@:
! invert the loop counter again
:$$ duplicate the value and pop both copies
'~- subtract '~' = 126
1-. subract 1 and print
@ terminate the program

\$\endgroup\$
2
\$\begingroup\$

Perl 5 -p, 27 bytes

/.(.{8})/;$_=-127+oct"0b$1"

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Nim, 58 bytes

import strutils
echo stdin.readAll[1..8].fromBin[:int]-127

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 13 bytes

I⁻⍘Φ…S⁹겦¹²⁷

Try it online! Link is to verbose version of code. Explanation:

     S          Input string
    … ⁹         Take first 9 characters
   Φ   κ        Remove first character
  ⍘     ²       Convert from base 2
 ⁻        ¹²⁷   Subtract 127
I               Cast to string
                Implicitly print
\$\endgroup\$
1
\$\begingroup\$

Canvas, 13 bytes

[]9@j{┤]2┴‾p-

Try it here!

Explanation

[]9@j{⊣]2⊥¯p⊣-
[]              get all prefixes
  9@            9th prefix
    j           remove first element
     {⊣]        cast each element to integer
        2⊥      decode from base 2
          ¯p    127
            -   subtract that from it 
\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js),  26  24 bytes

x=>'0b'+x.slice(1,9)-127

Try it online!

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.