【问题标题】:c - Multiplying Fractions with Bitwise Operationsc - 用按位运算乘分数
【发布时间】:2015-03-26 01:02:04
【问题描述】:

好的,所以我一直在试图找出如何将分数 (3/4) 乘以 c 中的有符号整数。挑战在于仅使用逻辑运算符(!~ & ^ | + >)而不使用(if 语句、循环等),并且最多使用 12 个逻辑运算符。目标是完全模仿以下表达式 (x*3/4)。现在,我查看了其他具有类似问题(只是分数不同)的问题,但是这些问题的解决方案使用了超过 12 个运算符。我尝试过简化它们,但如果解决方案不起作用,似乎就无法做到。这是 5/8 问题的解决方案:

int s = -((num >> 31) & 1); // sign bit as -1 or 0

int n = (num ^ s) - s; // twos complement if negative

int x = n >> 3; // divide by 8

x = (x << 2) + x;   // multiply by 5; no overflow yet since 5/8 is less than one

int y = n & 7;  // the bits we shifted out

y = (y << 2) + y;   // multiply by 5; no overflow

return (s ^ (x + (y >> 3))) - s; // the two pieces and complemented back

我不确定上述方法是否正确,因为我插入 -2 并手动完成并得到 -3 回来。应该是 -1,因为 -2 * (5/8) = -1.25

我最初解决这个问题的想法是检查和溢出。这是因为一个简单的程序,如:

x = (x<<1) + x;
x = X>>2;

在溢出的情况下会导致答案被 +1 关闭。为了解决这个问题,我认为我必须将限制除以 3 并检查相乘的整数是否大于 715827882 或 -715827882。如果数字更大,则从比较中获取 1 并将其添加到最终结果中,或者如果小于则获取 0 并将 0 添加到最终结果中。我觉得这种方式在没有 if 语句的情况下很难实现,而且它可能使用超过 12 个运算符。我只是在寻求解决问题的最佳方法的帮助。提前致谢!

【问题讨论】:

    标签: c bit-manipulation fractions


    【解决方案1】:

    你想到的是:

    x=(x<<1)+x; // do x=x*3 x=x>>2; // do x=x/4

    这可能会溢出,因为x 首先持有一个更大的值。这行得通吗?

    x=x-(x&gt;&gt;2); // do x=x-x/4, equal to 3/4

    当然,因为x&gt;&gt;2丢掉了最低位,所以结果被截断了。如果您需要截断,这是错误的,您应该使用加法:

    x=(x&gt;&gt;1)+((x+1)&gt;&gt;2); // x=x/2+x/4

    编辑:您需要(x+1)&gt;&gt;2 以避免双截断结果丢失,例如 x=7。

    【讨论】:

    • 很好的答案,尽管(x+1) 可能会溢出。
    • 减法不是列出的运算符之一,加法不适用于负数。
    • @user3386109 我认为您可以先使用按位运算符来检查数字是否为负数。
    • 没错,但这是任务的一部分,处理负数而不使用条件语句。
    • 感谢关于双重截断的建议,明天我会看看我想出什么,因为如果需要的话,我会整天处理这个问题:)
    猜你喜欢
    • 1970-01-01
    • 2022-06-16
    • 2022-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 2015-05-30
    相关资源
    最近更新 更多