相关疑难解决方法(0)

在C/C++中,什么是反转字节中位的顺序的最简单方法?

虽然有多种方法可以在一个字节中反转位顺序,但我很好奇开发人员实现的"最简单".通过颠倒我的意思是:

1110 -> 0111
0010 -> 0100
Run Code Online (Sandbox Code Playgroud)

这与 PHP问题类似,但不重复.

这与 C问题类似,但不重复.这个问题要求开发人员实施最简单的方法."最佳算法"涉及内存和CPU性能.

c c++ bit-manipulation

101
推荐指数
13
解决办法
14万
查看次数

为什么循环指令慢?英特尔无法有效实施吗?

LOOP(英特尔参考手动输入)递减ecx/rcx,然后如果非零则跳转.这很慢,但是英特尔不能廉价地把它变得很快吗? dec/jnz已经将宏观融合成 Sandybridge家族的一个 uop; 唯一的区别是设置标志.

loop关于各种微体系结构,来自Agner Fog的说明表:

  • K8/K10:7 m-ops
  • Bulldozer-family/Ryzen:1 m-op(与宏观融合测试和分支相同,或者jecxz)

  • P4:4次(相同jecxz)

  • P6(PII/PIII):8次
  • Pentium M,Core2:11 uops
  • Nehalem:6个uops.(11为loope/ loopne).吞吐量= 4c(loop)或7c(loope/ne).
  • SnB家族:7个uops.(11为loope/ loopne). 吞吐量=每5个循环一个,这是将循环计数器保留在内存中的瓶颈!jecxz只有2 uops,吞吐量与普通吞吐量相同jcc
  • Silvermont:7次
  • AMD Jaguar(低功耗):8 uops,5c吞吐量
  • 通过Nano3000:2 uops

难道解码器不能像lea rcx, [rcx-1]/ 那样解码jrcxz吗?这将是3 uops.至少那是没有地址大小前缀的情况,否则它必须使用ecx和截断RIP,EIP如果跳转; 也许奇怪的地址大小选择控制减量的宽度解释了许多uops?

或者更好,只需将其解码为不设置标志的融合分支和分支? dec ecx …

performance x86 assembly intel cpu-architecture

53
推荐指数
3
解决办法
6096
查看次数

反转Python整数的位

给定一个十进制整数(例如65),如何反转Python中的底层位?即.以下操作:

65 ? 01000001 ? 10000010 ? 130
Run Code Online (Sandbox Code Playgroud)

看来这个任务可以分为三个步骤:

  1. 将十进制整数转换为二进制表示
  2. 反转位
  3. 转换回十进制

步骤#2和3似乎很简单(见 SO问题关系到步骤#2),但我卡上的步骤1#.步骤#1的问题是检索带有填充零的完整十进制表示(即65 = 01000001,而不是1000001).

我四处寻找,但似乎找不到任何东西.

python bit-manipulation python-2.7

26
推荐指数
4
解决办法
4万
查看次数

反转位数

例如,我有二进制数1011,它等于十进制11.我希望反向位的位置使它变为1101,即十进制13.这是代码:

import java.util.*;
public class bits {
    public static void main(String[] args) {
        Scanner scnr=new Scanner(System.in);
        System.out.println("enter x:");
        int x=scnr.nextInt();
        int b=0;
        while (x!=0){
            b|=( x &1);
            x>>=1;
            b<<=1;
        }
        System.out.println(b);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我输入x 11然后它打印出来26.这是什么错误?

java

16
推荐指数
2
解决办法
3万
查看次数

这实际上是做什么的? - 疯狂的C++功能

我正在使用一些遗留代码,我遇到了一个函数,它显然用于在任意长的字段上执行网络字节顺序转换(大于ntohl可以处理的).

我无法理解它是否足以告诉它是否正在执行除了在msg缓冲区范围内反转字节顺序之外的任何事情(或者即使它会可靠地执行此操作).有人可以帮助我分解并分析它,以便我可以用更易于理解的东西(或者至少评论它)替换它!

void swapit(unsigned char *msg, int length) {
  for(;length>0;length--, msg++) {
    *msg = ((*msg * 0x0802LU & 0x22110LU) |
            (*msg * 0x8020LU & 0x88440LU)) *
           0x10101LU >> 16;
  }
}
Run Code Online (Sandbox Code Playgroud)

c++ networking

13
推荐指数
2
解决办法
787
查看次数

C无符号整数的反转位

我转换的无符号整数使用位运算符为二进制,和目前还整数&1,以检查是否比特是1或0,并且输出,然后通过1右移由2.然而的位被以错误的顺序返回到划分(反转),所以我想在开始之前反转整数中的位顺序.

有一个简单的方法吗?

示例:如果我给了unsigned int 10 = 1010

while (x not eq 0) 
  if (x & 1)
    output a '1'
  else 
    output a '0'
  right shift x by 1
Run Code Online (Sandbox Code Playgroud)

这会返回0101这是不正确的...所以我想在运行循环之前反转最初的位顺序,但我不确定如何做到这一点?

c binary int unsigned bit-manipulation

10
推荐指数
1
解决办法
4万
查看次数

你会如何转置二进制矩阵?

我在C++中有二进制矩阵,我用8位值向量重复.

例如,以下矩阵:

1 0 1 0 1 0 1
0 1 1 0 0 1 1
0 0 0 1 1 1 1
Run Code Online (Sandbox Code Playgroud)

表示为:

const uint8_t matrix[] = {
    0b01010101,
    0b00110011,
    0b00001111,
};
Run Code Online (Sandbox Code Playgroud)

我这样做的原因是因为然后计算这样的矩阵和8位向量的乘积变得非常简单和有效(每行只有一个按位AND和奇偶校验计算),这比单独计算每个位.

我现在正在寻找一种有效的方法来转置这样的矩阵,但是我无法弄清楚如何在不必手动计算每个位的情况下进行转换.

只是为了澄清一下,对于上面的例子,我想从转置中得到以下结果:

const uint8_t transposed[] = {
    0b00000000,
    0b00000100,
    0b00000010,
    0b00000110,
    0b00000001,
    0b00000101,
    0b00000011,
    0b00000111,
};
Run Code Online (Sandbox Code Playgroud)

注意:我更喜欢一种算法,它可以用任意大小的矩阵来计算,但我也对只能处理某些大小的算法感兴趣.

c++ math binary transpose matrix

10
推荐指数
3
解决办法
2780
查看次数

C中的反转位模式

我正在将数字转换为二进制数,并且必须使用它putchar来输出每个数字.

问题是我正在接受订单.

在做自己的后缀之前,有没有反转数字位模式?

因为在int中有一个特定的位模式 - 我该如何反转这个位模式?

c

8
推荐指数
2
解决办法
5215
查看次数

32位字的镜像位

你会怎么用C做的?(例如:如果我们必须镜像8位,则10110001变为10001101).某些处理器上是否有任何可以简化此任务的说明?

c assembly bit-manipulation

7
推荐指数
2
解决办法
2万
查看次数

最快的64位人口数(汉明重量)

我必须计算汉明重量以获得相当快速的连续64位数据流,并且使用popcnt汇编指令引起了我的一个例外,即我的英特尔酷睿i7-4650U.

我检查了我的圣经黑客的喜悦,并扫描了网络上的各种算法(因为他们在计算机诞生时开始解决这个'问题',所以这里有很多算法).

我在周末玩了一些我自己的想法并提出了这些算法,我几乎可以将数据移入和移出CPU.

    //64-bit popcnt using BMI2
_popcnt_bmi2:
        mov         (%rdi),%r11
        pext        %r11,%r11,%r11
        not         %r11
        tzcnt       %r11,%r11
        mov         %r11,(%rdx)
        add         $8h,%rdi
        add         $8h,%rdx
        dec         %rsi
        jnz         _popcnt_bmi2
        ret
Run Code Online (Sandbox Code Playgroud)

在上面的代码中我使用pext(BMI2),其中输入数据使用自身作为掩码.然后,所有存在的位将从结果寄存器中的最低有效位(本身再次)开始崩溃.然后我需要计算折叠位的数量,所以我反转所有位然后tzcnt用来计算现在为零的数量.我认为这是一个相当不错的主意.

然后我也尝试了AVX2方法:

//64-bit popcnt using AVX2
_popcnt_avx2:
        vmovdqa     (%rcx),%ymm2
        add         $20h,%rcx
        vmovdqa     (%rcx),%ymm3
        add         $20h,%rcx
        vmovdqa     (%rcx),%ymm4
popcnt_avx2_loop:
        vmovdqa     (%rdi),%ymm0
        vpand       %ymm0, %ymm2, %ymm1
        vpandn      %ymm0, %ymm2, %ymm0
        vpsrld      $4h,%ymm0, %ymm0
        vpshufb     %ymm1, %ymm3, %ymm1
        vpshufb     %ymm0, %ymm3, %ymm0
        vpaddb      %ymm1,%ymm0,%ymm0       //popcnt (8-bits)
        vpsadbw     %ymm0,%ymm4,%ymm0       //popcnt (64-bits) …
Run Code Online (Sandbox Code Playgroud)

optimization performance assembly simd avx

6
推荐指数
1
解决办法
1732
查看次数