从整数中清除最高有效位


29

输入值

输入是单个正整数 n

输出量

输出n的最高有效位设置为0

测试用例

1 -> 0
2 -> 0
10 -> 2
16 -> 0
100 -> 36
267 -> 11
350 -> 94
500 -> 244

例如:350in二进制为101011110。设置其最高有效位(即最左边的1位)以0使其变成001011110等于十进制整数94的输出。这是OEIS A053645


19
清除从最显著位10显然给0:d
clabacchio

@clabacchio I .....呃... (不错)
Baldrickk

12
在我看来,零和零一样重要。当您说“最高有效位”时,您的意思是“设置为1的最高有效位”。
Michael Kay

Answers:


12

C(gcc)49 44 40 39字节

i;f(n){for(i=1;n/i;i*=2);return n^i/2;}

在线尝试!


1
您可以替换i<=nn/i的-1字节。这不是我的高尔夫,其他人试图将其编辑到您的帖子中,但是我将其回滚了,因为根据我们的社区规则,不接受高尔夫帖子的编辑。
HyperNeutrino

1
我刚刚看到并批准了@HyperNeutrino。没意识到那条规则,但这是一个不错的高尔夫球技巧!
cleblanc

啊好吧。是的,通常人们应该发表有关高尔夫球技巧的评论,OP应该进行编辑,但是如果您接受了它,那么实际上并不是什么大问题。:)
HyperNeutrino


9

05AB1E,5个字节

.²óo-

在线尝试!

从整数N中去除最高有效位等效于找到从N到比N低的最高整数2的距离。

因此,我使用了公式 N-2 floor(log 2 N)

  • -以2为底的对数。
  • ó -取整为整数。
  • o- 2升高到上述结果的功率。
  • - - 区别。

1
b¦C也可以...对吗?转换为二进制,MSB始终位于索引1,删除MSB,再转换回。
魔术章鱼缸

2
@MagicOctopusUrn没错,失败了1
Xcoder先生17年

8

果冻,3个字节

BḊḄ

在线尝试!

说明

BḊḄ  Main Link
B    Convert to binary
 Ḋ   Dequeue; remove the first element
  Ḅ  Convert from binary

2
是不是两个字节的代码点?这会将整体大小更改为5个字节。
Bartek Banachewicz

3
@BartekBanachewicz Jelly使用其自己的代码页,其中这些字符仅为1个字节。
steenbergh

1
感谢您提出和回答此问题,这困扰了我很长时间!
Ukko

8

C(gcc)-59个字节

main(i){scanf("%d",&i);return i&~(1<<31-__builtin_clz(i));}

这个gcc答案仅使用整数按位和算术运算。这里没有对数!输入0可能会有问题,并且是完全不可移植的。

这是我在此网站上的第一个答案,因此,我希望能提供反馈和改进。我肯定对学习按位表达式很开心。


1
欢迎使用PPCG,这是一个很好的第一答案!我们希望您喜欢参与更多挑战:-)
ETHproductions'Nov

您不需要一个完整的程序main一个函数是一个有效的提交。将其更改为函数并将输入作为该函数的参数节省18个字节
Steadybox

1
您甚至可以将其写为宏来节省另外两个字节
Steadybox

7

MATL8 6字节

B0T(XB

在线尝试!

多亏了Cinaski,节省了两个字节。切换到分配索引而不是引用索引的时间缩短了2个字节:)

说明:

          % Grab input implicitly: 267
B         % Convert to binary: [1 0 0 0 0 1 0 1 1]
 0T(      % Set the first value to 0: [0 0 0 0 0 1 0 1 1]
    XB    % Convert to decimal: 11

1
如果您使用4L而不是,则可以使用引用索引(也为6个字节)[2J]。另一个有趣的6个字节:(tZlcW-仅适用于MATLAB,不适用于TIO / Octave)
Sanchises

6

Java(OpenJDK 8),23字节

n->n^n.highestOneBit(n)

在线尝试!

对不起,内置:-/


Java具有内置功能,而其他一些流行的语言(如.NET和Python)还没有?o.Ô+1。即将发布更长的内容而没有内置程序。.您的长度缩短了15个字节。XD
Kevin Cruijssen

@KevinCruijssen类似的东西n->n^1<<(int)Math.log2(n)将起作用,并且可能少于38个字节。如果这highestOneBit不能正常工作,这是我的第二个想法(尚未经过测试)。出于好奇,您的解决方案是什么
OlivierGrégoire17年

我的是n->n^1<<(int)(Math.log(n)/Math.log(2))因为Math.log2Java中不存在。; p只能Math.logMath.log10Math.loglp可用。
凯文·克鲁伊森

2
我打算发布相同的内容,只有减号而不是xor。记得从方法
JollyJoker

1
@KevinCruijssen糟糕,Math.log2确实不存在...我的坏。看到?highestOneBit存在一种不错的方法(),但没有另一种(Math.log2)。Java很奇怪;-)
OlivierGrégoire17年

6

外壳,3 个字节

ḋtḋ

在线尝试!

说明:

    -- implicit input, e.g. 350
  ḋ -- convert number to list of binary digits (TNum -> [TNum]): [1,0,1,0,1,1,1,1,0]
 t  -- remove first element: [0,1,0,1,1,1,1,0]
ḋ   -- convert list of binary digits to number ([TNum] -> TNum): 94

类似于果冻的解决方案,这似乎是它实际上是5个字节,而不是3
鲍尔泰克Banachewicz

1
@BartekBanachewicz类似于果冻,果壳使用自己的代码页,所以这实际上是3个字节:P
HyperNeutrino

@BartekBanachewicz参见此处的代码页:github.com/barbuz/Husk/wiki/Codepage
Laikoni


5

Python 2,27个字节

lambda n:n-2**len(bin(n))/8

在线尝试!

说明

lambda n:n-2**len(bin(n))/8  # Lambda Function: takes `n` as an argument
lambda n:                    # Declaration of Lambda Function
              len(bin(n))    # Number of bits + 2
           2**               # 2 ** this ^
                         /8  # Divide by 8 because of the extra characters in the binary representation
         n-                  # Subtract this from the original

...只是在我进行按位运算时。:P
totallyhuman

@totallyhuman嘿,对不起,但击败了您:P
HyperNeutrino

2**len(bin(n))/8也可以拼写1<<len(bin(n))-3,然后它将同时在2和3中工作(不保存/添加字节)。
Mego

@Mego Cool,感谢您的加入!
HyperNeutrino

5

Python 3,30个字节

-8字节归功于Caird coinheringaahing。我是从记忆中输入的。:o

lambda n:int('0'+bin(n)[3:],2)

在线尝试!



好吧,a)会在1上出错,b)我很愚蠢,没想到。但是我确实做了一个小的更改来解决它。谢谢!
totallyhuman

我已经编辑了代码,使其能够正常工作(并节省了4个字节)
caird coinheringaahing

那仍然在1错误。
21:08完全人类

@cairdcoinheringaahing那是我最初的答案,但后来我意识到它在1上出错。解决方法的结束时间比简单的XOR方法还要长
FlipTack


4

JavaScript,22 20字节

由于ovs,节省了2个字节

a=>a^1<<Math.log2(a)

在线尝试!

另一种方法,32字节

a=>'0b'+a.toString`2`.slice`1`^0

在线尝试!


你为什么要什么.slice`1`^0时候.slice(1)^0做得很好,哈哈
ETHproductions

@ETHproductions. This one looks better :)

4

J, 6 bytes

}.&.#:

Pretty simple.

Explanation

}.&.#:
    #:  convert to list of binary digits
  &.    apply right function, then left, then the inverse of right
}.      behead

I was going to post this :(
Cyoce

@Cyoce Me too...
Adám

4

APL (Dyalog), 10 bytes

Tacit prefix function.

212∘⊥⍣¯1

Try it online!

2∘⊥… decode from base-2…
 …⍣¯1 negative one time (i.e. encode in base-2)

1↓ drop the first bit

2⊥ decode from base-2


4

Ruby, 26 bytes

-7 Bytes thanks to Ventero. -2 Bytes thanks to historicrat.

->n{/./=~'%b'%n;$'.to_i 2}

You can save a few bytes by just skipping the first character and dropping redundant parentheses: ->n{n.to_s(2)[1..-1].to_i 2}
Ventero

->n{/./=~'%b'%n;$'.to_i 2}
histocrat

4

C (gcc), 38 bytes

Built-in in gcc used.

f(c){return c^1<<31-__builtin_clz(c);}

Replacing 31- with ~ should save two bytes.

@ThePirateBay it depends on hardware whether the shift is masked. On my computer, it will output 0.
Colera Su

4

ARM Assembly, 46 43 bytes

(You can omit destination register on add when same as source)

clz x1,x0
add x1,1
lsl x0,x1
lsr x0,x1
ret

What flavour of ARM assembly syntax is this? My GNU assembler doesn't understand shr/shl/ret and wants instead something like lsr/lsl/bx lr.
Ruslan

Probably mixing syntax across multiple versions (ret is from aarch64), though I thought that the assembler would pseudo op these for you. For purposes of here, though, using the older and direct lsl/lsr is probably correct.
Michael Dorgan

Funny thing, i can do it in 1 less operation, but I the byte size goes up by 2. Ah code golf.
Michael Dorgan

3

Pyth, 5 bytes

a^2sl

Test suite.

Explanation:

    l   Log base 2 of input.
   s    Cast ^ to integer (this is the position of the most significant bit.)
 ^2     Raise 2 to ^ (get the value of said bit)
a       Subtract ^ from input

3

Alice, 8 bytes

./-l
o@i

Try it online!

Explanation

.   Duplicate an implicit zero at the bottom of the stack. Does nothing.
/   Switch to Ordinal mode, move SE.
i   Read all input as a string.
l   Convert to lower case (does nothing, because the input doesn't contain letters).
i   Try reading all input again, pushes an empty string.
/   Switch to Cardinal mode, move W.
.   Duplicate. Since we're in Cardinal mode, this tries to duplicate an integer.
    To get an integer, the empty string is discarded implicitly and the input is 
    converted to the integer value it represents. Therefore, at the end of this,
    we get two copies of the integer value that was input.
l   Clear lower bits. This sets all bits except the MSB to zero.
-   Subtract. By subtracting the MSB from the input, we set it to zero. We could
    also use XOR here.
/   Switch to Ordinal, move NW (and immediately reflect to SW).
o   Implicitly convert the result to a string and print it.
/   Switch to Ordinal, move S.
@   Terminate the program.

3

Japt, 6 bytes

^2p¢ÊÉ

Try it online!

Explanation

^2p¢ÊÉ
   ¢     Get binary form of input
    Ê    Get length of that
     É   Subtract 1
 2p      Raise 2 to the power of that
^        XOR with the input

If input 1 can fail: 4 bytes

¢Ån2

Try it online!

Explanation: get input binary (¢), slice off first char (Å), parse as binary back to a number (n2).




3

CJam, 7 bytes

{2b()b}

Try it online!

Explanation:

{     }  Block:         267
 2b      Binary:        [1 0 0 0 0 1 0 1 1]
   (     Pop:           [0 0 0 0 1 0 1 1] 1
    )    Increment:     [0 0 0 0 1 0 1 1] 2
     b   Base convert:  11

Reuse the MSB (which is always 1) to avoid having to delete it; the equivalent without that trick would be {2b1>2b} or {2b(;2b}.


3

Retina, 15 13 bytes

^(^1|\1\1)*1

Try it online!

Input and output in unary (the test suite includes conversion from and to decimal for convenience).

Explanation

This is quite easy to do in unary. All we want to do is delete the largest power of 2 from the input. We can match a power of 2 with some forward references. It's actually easier to match values of the form 2n-1, so we'll do that and match one 1 separately:

^(^1|\1\1)*1

The group 1 either matches a single 1 at the beginning to kick things off, or it matches twice what it did on the last iteration. So it matches 1, then 2, then 4 and so on. Since these get added up, we're always one short of a power of 2, which we fix with the 1 at the end.

Due the trailing linefeed, the match is simply removed from the input.


3

R, 28 bytes

function(x)x-2^(log2(x)%/%1)

Try it online!

Easiest to calculate the most significant bit via 2 ^ floor(log2(x)) rather than carry out base conversions, which are quite verbose in R


3

PARI/GP, 18 bytes

n->n-2^logint(n,2)

Alternate solution:

n->n-2^exponent(n)

The first one seems to give wrong answers. Should it be n->n-2^logint(n,2)? The second one is not supported in my version of PARI/GP, nor in the version used by tio.run. Is that a new function?
Jeppe Stig Nielsen

@JeppeStigNielsen Oops, fixed -- that's what I get for submitting from my phone. Yes, the second one is a new function.
Charles

@JeppeStigNielsen I just checked, exponent was added 5 days ago, compared to this challenge which was added yesterday. :)
Charles



3

Excel, 36 31 bytes

-5 bytes thanks to @IanM_Matrix1

=BIN2DEC(MID(DEC2BIN(A1),2,99))

Nothing interesting.


Reduce the size to 31 bytes by replacing REPLACE with a MID: =BIN2DEC(MID(DEC2BIN(A1),2,99))
IanM_Matrix1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.