标签: bit-manipulation

使用按位运算符时出现分段错误

我目前正在搞一个 C 项目,它将接收两个 8 位二进制数并将它们转换为十进制值。我对 C 中的按位运算符以及它们如何处理数字有很好的理解,我的问题是围绕语法的问题。

ATM我的程序很简单:

int main() {
  char *inp1;
  char *inp2;
  unsigned long binNum1;
  unsigned long binNum2;

  printf("Enter the first binary number: "); 
  scanf("%s", inp1); 
  printf("Enter the second binary number: "); 
  scanf("%s", inp2); 

  binNum1 = strtoul(inp1, NULL, 2);
  binNum2 = strtoul(inp1, NULL, 2);

  unsigned long orVal = binNum1 | binNum2;
  unsigned long andVal = binNum1 & binNum2;
  unsigned long exclVal = binNum1 ^ binNum2;

  printf("Your or value is: %lu", orVal);
  printf("Your and value is: %lu", andVal); …
Run Code Online (Sandbox Code Playgroud)

c binary bit-manipulation decimal

0
推荐指数
1
解决办法
885
查看次数

了解如何使用 C 中的按位运算符计算数字的尾随零

注意- 这不是这个问题的重复 -并行计算右侧的连续零位(尾随):解释?signed()链接的问题有不同的上下文,它只询问使用的目的。不要将此问题标记为重复。

我一直在寻找一种方法来获取数字中尾随零的数量。我发现斯坦福大学在这里写了一篇有点无聊的文章,给出了以下解释。

unsigned int v;      // 32-bit word input to count zero bits on right
unsigned int c = 32; // c will be the number of zero bits on the right
v &= -signed(v);
if (v) c--;
if (v & 0x0000FFFF) c -= 16;
if (v & 0x00FF00FF) c -= 8;
if (v & 0x0F0F0F0F) c -= 4;
if (v & 0x33333333) c -= 2;
if (v & 0x55555555) c …
Run Code Online (Sandbox Code Playgroud)

c hex bit-manipulation bit-shift

0
推荐指数
1
解决办法
1946
查看次数

`rand.Intn` 函数的内部工作原理 - GoLang

不知何故,我碰巧查看了 Go 的源代码,了解它如何在传递数组长度时实现 Random 函数。

这是调用代码

func randomFormat() string {
    formats := []string{
        "Hi, %v. Welcome!",
        "Great to see you, %v!",
        "Hail, %v! Well met!",
    }
    return formats[rand.Intn(len(formats))]
}

Run Code Online (Sandbox Code Playgroud)

Go源代码:主要部分

func (r *Rand) Intn(n int) int {
    if n <= 0 {
        panic("invalid argument to Intn")
    }
    if n <= 1<<31-1 {
        return int(r.Int31n(int32(n)))
    }
    return int(r.Int63n(int64(n)))
}
Run Code Online (Sandbox Code Playgroud)

Go 源代码:参考部分 - 大多数开发人员已经将其安装在他们的机器或 go 存储库上。

// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
// …
Run Code Online (Sandbox Code Playgroud)

bit-manipulation go random-seed

0
推荐指数
1
解决办法
1500
查看次数

Java 中的无符号模

我正在移植一些在 uint32_t 上进行取模的 C 代码。uint32_t 按位适合 Java int,但我无法弄清楚如何在不转换为 long 的情况下对其执行模运算。这是我现在的代码:

int i = 0xffffffff;
long asUnsigned = Integer.toUnsignedLong(i);
int mod = (int) (asUnsigned % 42L);
Run Code Online (Sandbox Code Playgroud)

我可以在不转换为长整型的情况下执行此模计算吗?

java bit-manipulation modulo unsigned-integer signed-integer

0
推荐指数
1
解决办法
633
查看次数

将四个 1 字节变量连接成一个 4 字节字时,哪种移位和 OR 方法更快?(比较生成的汇编代码)

因此,我目前正在研究按位运算符和位操作,并且遇到了两种不同的方法将四个 1 字节字组合成一个 4 字节宽字。

下面给出了两种方式

找到这两种方法后,我比较了两者生成的反汇编代码(使用带 -O2 标志的 gcc 11 编译),我没有反汇编及其生成的代码的基本知识,我只知道代码越短,函数速度越快(大多数时候我猜......也许有一些例外),现在对于这两种方法来说,它们在生成的反汇编代码中似乎具有相同的行数/行数,所以我猜他们的表现是一样的?

我也对指令的顺序感到好奇,第一种方法似乎交替其他指令sal>or>sal>or>sal>or,而第二种方法更统一,sal>sal>sal>or>or>mov>or这对性能是否有一些重大影响,例如,如果我们正在处理更大的单词?


两种方法

int method1(unsigned char byte4, unsigned char byte3, unsigned char byte2, unsigned char byte1)
{
    int combine = 0;
    combine = byte4;
    combine <<=8;
    combine |= byte3;
    combine <<=8;
    combine |= byte2;
    combine <<=8;
    combine |= byte1;
    return combine;
}

int method2(unsigned char byte4, unsigned char byte3, unsigned char byte2, unsigned char byte1)
{
    int combine = 0, temp;
    temp = byte4;
    temp …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly bit-manipulation micro-optimization

0
推荐指数
1
解决办法
488
查看次数

当无符号字符与 11100000 进行 OR 运算时,为什么按位 OR 运算无法按预期工作?

我无法理解为什么操作 'c | 11100000' 似乎不起作用。但我也注意到 'c | 10000000' 按预期工作。

#include <stdio.h>

int main()
{
    unsigned char c, c1;
    
    c = c & 0;
    c = c | 11100000;
    printf("%o \t", c);
    
    /** prints 140 ***/
    
    
    c = c & 0;
    c = c | 111;
    c << 5;
    printf("%o", c);
    
    /** prints 157 **/

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c bit-manipulation bit-shift bitwise-operators bitwise-or

0
推荐指数
1
解决办法
206
查看次数

C strtol 如何解释十六进制字符串?

我期望strtol("ffffffffffffffff", NULL, 16)return-1strtol("7fffffffffffffff", NULL, 16)return LONG_MAX,因为linux 手册页第一句话似乎暗示 strtol 返回signed long 。第二次调用确实返回了预期的结果。但是第一个调用返回了LONG_MAX!就像,输入的十六进制字符串甚至不相同。好像这还不够令人困惑,strtol("8000000000000000", NULL, 16)我期望返回的LONG_MIN,返回与前两个调用 相同的值LONG_MAX。对于前两次调用,我认为 strtol 忽略了输入字符串中的最高有效位,但第三次调用驳斥了这一假设。

这是某种奇怪的铸造情况还是我将数学现实与 C 现实混合在一起?

这是我的源代码:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[]) {
    long x = strtol(argv[1], NULL, 16);
    printf("%ld\n", x);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我正在 Ubuntu 上进行编译gcc scratch.c,并通过将十六进制字符串作为命令行参数传递来获取结果。例如:

./a.out ffffffffffffffff // gives LONG_MAX
./a.out 8000000000000000 // gives LONG_MAX
./a.out 7fffffffffffffff // gives LONG_MAX
Run Code Online (Sandbox Code Playgroud)

c hex bit-manipulation long-integer

0
推荐指数
1
解决办法
1013
查看次数

如何在 C 中打印 1 位(不仅仅是最低有效位)?

我正在开发一个发送 TCP 标头的程序(模拟 3 次握手)。我有一个变量,该变量包含数据偏移量(3 位)、保留值(4 位)和 9 个标志(9 位)。我正在使用按位运算来设置位。问题是如何打印每个位?

  1. 假设我存储从 2 到 4(从左到右)开始的数据偏移量:例如。0111000000000000

如何打印这 3 位?多变的:

u_int16_t reserved_ofs_flags;
Run Code Online (Sandbox Code Playgroud)

我发现这个问题类似,但答案只适用于最不重要的问题:如何打印一位?

c bit-manipulation

0
推荐指数
1
解决办法
310
查看次数

ROL 操作后溢出标志设置为 1,即使它应该是未定义的

我正在使用 emu8086 学习 8086 汇编,我正在玩一些旋转指令,至于我的问题,我知道对于超过 1 位移位/旋转,溢出标志 OF 的行为是未定义的。

但是当我尝试下面的代码时

MOV BH,72H

MOV CL,4

ROL BH,CL
Run Code Online (Sandbox Code Playgroud)

BH 寄存器中的结果为 27H,并且至于标志,进位和溢出标志被设置为 1,即使 OF 不应该被设置,因为它是未定义的。

有人可以解释一下 OF 是如何以及为什么设置在这里的吗?

x86 assembly bit-manipulation eflags emu8086

0
推荐指数
1
解决办法
139
查看次数

Assembly x86 MASM - 从内存中提取 5 位的问题

我有一个问题需要解决,但我不知道如何解决。我正在询问如何解决这个问题的一般想法。我有一个内存地址,在 ESI 中。内存代表某种简化的 ASCII 编码,其中 5 位依次表示一个特定字符。内存以五位结尾 - 00000b。为了转换为正常的 8 位 ASCII,必须将 60H 添加到每个 5 位值中。我想将每个 5 位编码字符存储为地址 EDI 下的 8 位 ASCII 编码。EDI 也必须以 0 - 00000000b 结尾。

示例: [ESI] = 00011 00010 11010 00000b [EDI] = 01100011 01100010 01111010 00000000b

我将如何从 esi 中逐个提取每 5 位?

x86 assembly bit-manipulation masm bit-fields

0
推荐指数
1
解决办法
173
查看次数