c - 在二进制中,从有符号数转换为二进制补码。全部在 C 中

标签 c puzzle bit limits

我有一个有趣的谜题。我需要将有符号数(例如 -5 (0x80000005))转换为二进制补码 -5 (0xFFFFFFFB)。我唯一可以使用的运算符是 !、~、&、^、|、+、<<、>> 以及最多 15 个运算符与我想要的任意数量的变量的任意组合。 = 可以使用,但不计入运算符总数。此外,不得使用“if”语句、循环或调用任何类型的函数。

函数看起来像

int sign2two(int x){
//... some stuff here
return x;
}

我遇到的问题是我可以查明数字是否为负数。但我想说,如果 num 为负数,则翻转位并加 1。否则返回数字。我不知道该怎么做。谢谢。

最佳答案

这些问题在我看来是极其愚蠢的...

#include <stdint.h>
#include <stdio.h>

int32_t test1(uint32_t x) {
    const uint32_t sign  = (x & 0x80000000); // Total operations: 1
    const uint32_t value = (x & 0x7FFFFFFF); // Total operations: 2

    // Let's create a value N, where N is equal to:
    // if (sign)
    //     N = 0xFFFFFFFF;
    // else
    //     N = 0x00000000;
    uint32_t N = sign;  // Total operations: 2
    N = N | (N >> 1);   // Total operations: 4 
    N = N | (N >> 2);   // Total operations: 6
    N = N | (N >> 4);   // Total operations: 8
    N = N | (N >> 8);   // Total operations: 10
    N = N | (N >> 16);  // Total operations: 12

    // Let's create a value MaybeOne, where MaybeOne is equal to:
    // if (sign)
    //     MaybeOne = 1;
    // else
    //     MaybeOne = 0;
    uint32_t MaybeOne = N & 0x1; // Total operations: 13

    // Now, Let's perform the following step:
    // if (sign)
    //     return (value ^ 0xFFFFFFFF) + 1;
    // else
    //     return (value ^ 0x00000000) + 0;
    return (value ^ N) + MaybeOne; // Total operations: 15
}

int32_t test2(uint32_t x) {
    int32_t sign = (x & 0x80000000);
    int32_t value = (x & 0x7FFFFFFF);

    if (sign)
        return -value;
    else
        return value;
}

int main() {
    uint32_t i;
    for (i=0; i<0xFFFFFFFF; ++i) 
        if (test1(i) != test2(i))
            printf("0x%08x\n", i);
}

此外,使用来自 Eric Postpischil 的评论,我们可以显着减少操作次数:

int32_t test3(uint32_t x) {
    const uint32_t sign  = (x >> 31);        // Total operations: 1
    const uint32_t value = (x & 0x7FFFFFFF); // Total operations: 2

    // Let's create a value N, where N is equal to:
    // if (sign)
    //     N = 0xFFFFFFFF;
    // else
    //     N = 0x00000000;
    const uint32_t N = ~sign + 1;  // Total operations: 4

    // Let's create a value MaybeOne, where MaybeOne is equal to:
    // if (sign)
    //     MaybeOne = 1;
    // else
    //     MaybeOne = 0;
    uint32_t MaybeOne = sign; // Total operations: 4

    // Now, Let's perform the following step:
    // if (sign)
    //     return (value ^ 0xFFFFFFFF) + 1;
    // else
    //     return (value ^ 0x00000000) + 0;
    return (value ^ N) + MaybeOne; // Total operations: 6
}

关于c - 在二进制中,从有符号数转换为二进制补码。全部在 C 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21918419/

相关文章:

c - 从 c 函数返回一个二维数组

c++ - 在opencv中聚类图像片段

architecture - 为什么位数总是(?)2的幂?

cpu功耗和设置位

c - R*-Tree C 实现?

ios - 如何从 C 方法调用 Objective-C "self"

java - TreeSet搜索花费很长时间,谜题: to find lucky numbers

javascript - 十五益智游戏

java - 设计一个比较器来排序单词,以便每个单词的最后一个字母是下一个单词的第一个字母?

java - 将 2 个 32 位整数交织成 64 位整数