我目前正在搞一个 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) 注意- 这不是这个问题的重复 -并行计算右侧的连续零位(尾随):解释?。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) 不知何故,我碰巧查看了 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) 我正在移植一些在 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
因此,我目前正在研究按位运算符和位操作,并且遇到了两种不同的方法将四个 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 | 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) 我期望strtol("ffffffffffffffff", NULL, 16)return-1和strtol("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) 我正在开发一个发送 TCP 标头的程序(模拟 3 次握手)。我有一个变量,该变量包含数据偏移量(3 位)、保留值(4 位)和 9 个标志(9 位)。我正在使用按位运算来设置位。问题是如何打印每个位?
如何打印这 3 位?多变的:
u_int16_t reserved_ofs_flags;
Run Code Online (Sandbox Code Playgroud)
我发现这个问题类似,但答案只适用于最不重要的问题:如何打印一位?
我正在使用 emu8086 学习 8086 汇编,我正在玩一些旋转指令,至于我的问题,我知道对于超过 1 位移位/旋转,溢出标志 OF 的行为是未定义的。
但是当我尝试下面的代码时
MOV BH,72H
MOV CL,4
ROL BH,CL
Run Code Online (Sandbox Code Playgroud)
BH 寄存器中的结果为 27H,并且至于标志,进位和溢出标志被设置为 1,即使 OF 不应该被设置,因为它是未定义的。
有人可以解释一下 OF 是如何以及为什么设置在这里的吗?
我有一个问题需要解决,但我不知道如何解决。我正在询问如何解决这个问题的一般想法。我有一个内存地址,在 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 位?
bit-manipulation ×10
c ×6
assembly ×3
x86 ×3
bit-shift ×2
hex ×2
binary ×1
bit-fields ×1
bitwise-or ×1
decimal ×1
eflags ×1
emu8086 ×1
go ×1
java ×1
long-integer ×1
masm ×1
modulo ×1
random-seed ×1