【问题标题】:Problems with Bit Shifting and Type Casting when Implementing Booth's Algorithm实现 Booth 算法时的位移和类型转换问题
【发布时间】:2016-05-28 14:45:14
【问题描述】:

我正在编写一个实现Booth's Algorithm 以乘以整数的程序。我只被允许使用位级运算符、逻辑运算符和位移。我被允许为程序循环一个循环,以及一个将添加两个整数的函数。 我无法理解我的程序出了什么问题。当我使用按位运算符来屏蔽 long long 的一半时,我得到的值不正确。关于我在那里做错的任何建议?也许我不明白如何正确掩盖。它也可能与类型转换有关;我真的不确定。提前感谢您的帮助!

这里是代码:

#include <stdio.h>

int Add (int x, int y);
long long Booth (int x, int y);

int main() {
    int hex1, hex2;
    long long product;
    printf("\nEnter Multiplicand & Multiplier in hex: ");
    scanf(" %x %x", &hex1, &hex2);

    product = Booth(hex1, hex2);

    printf("Multiplicand = 0x%08X \tAs signed = %+d\n", hex1, hex1);
    printf("Multiplier = 0x%08X \tAs signed = %+d\n", hex2, hex2);
    printf("Product = 0x%16X \tAs signed = %+d\n", product, product);
}

int Add (int x, int y) {
    return x + y;
}

long long Booth (int multiplicand, int multiplier) {
    int i;
    long long product;
    long long productLH;
    long long productRH;
    int productLHI;
    int productRHI;
    int cOut;
    int negMultiplicand;
    negMultiplicand = Add (~multiplicand, 1);
    product = (long long) Add (0, multiplier);

    for (i = 0; i < 32; i++) {
        if (((product & 1) == 1) && (cOut == 0)) {
            //Mask left half and right half of product
            productLH = (product & 0xFFFFFFFF00000000);
            productRH = (product & 0x00000000FFFFFFFF);

            //Bit shift product so all values are in lower 32 bits
            productLH = (productLH >> 32);

            //Convert left halves and right halves to ints
            productLHI = (int) (productLH & 0x00000000FFFFFFFF);
            productRHI = (int) productRH & (0x00000000FFFFFFFF);
            productLHI = Add(productLHI, negMultiplicand);

            //Put halves back together
            product = (long long) Add(productLHI, 0);
            product = ((product << 32) & 0xFFFFFFFFFFFFFFFF);
            product = (long long) Add((int)product, productRHI);
        }   
        else if (((product & 1) == 0) && (cOut == 1)) {
            //Mask left half and right half of product
            productLH = (product & 0xFFFFFFFF00000000);
            productRH = (product & 0x00000000FFFFFFFF);

            //Bit shift product so all values are in lower 32 bits
            productLH = (productLH >> 32);

            //Convert left halves and right halves to ints
            productLHI = (int) (productLH & 0x00000000FFFFFFFF);
            productRHI = (int) productRH & (0x00000000FFFFFFFF);
            productLHI = Add(productLHI, multiplicand);

            //Put halves back together
            product = (long long) Add(productLHI, 0);
            product = ((product << 32) & 0xFFFFFFFFFFFFFFFF);
            product = (long long) Add((int)product, productRHI);
        }
        cOut = (product & 1);
        product = product >> 1;
    }
    return product;
}

【问题讨论】:

  • 您应该为long long 使用正确的格式说明符:%lld(或%llX 用于十六进制)。此外,produceCopy1 没有定义; cOut 在初始化之前也会被读取。
  • 您必须将其初始化为适合您的算法的值。是零吗?然后int cOut = 0;.
  • 我已经这样做了,但我的问题仍然没有解决。谢谢你注意到这一点,我看的时候没看到。我相信错误与我的位掩码和类型转换有关。我不确定那有什么问题。
  • 有符号值的位移是有问题的。见Arithmetic bit-shift on a signed integer
  • 让你的所有类型都是无符号的,并在你的十六进制常量上使用ULL 后缀

标签: c algorithm casting bit-manipulation


【解决方案1】:

除了 rslemos 注意到的错误,还有两点需要纠正:

  1. 整数常量0xFFFFFFFF00000000 和0xFFFFFFFFFFFFFFFF 需要后缀LL。
  2. 向product 添加内容时,添加的值不得符号扩展。因此,改变

        product = (long long) Add (0, multiplier);
    

    到

        product = (unsigned)multiplier; // do not sign-extend multiplier
    

    和

                product = (long long) Add((int)product, productRHI);
    

    到

                product |= (unsigned)productRHI;    // do not sign-extend productRHI
    

    (出现两次)。

【讨论】:

    【解决方案2】:

    您不需要那些面具来解决问题。如果掩码是问题,只需按位或乘积和乘法器,这会将 64 位乘积的低 32 位设置为您想要的“右半部分”。然后,只需将乘积向右移动 32 位,在您的加法函数调用中转换为 int。这会将 64 位二进制截断为 32 位二进制。

    PS。前一天晚上开始 Babic 的实验室作业可确保您度过一段糟糕的时光……

    【讨论】:

      【解决方案3】:

      函数 Add() 的返回可能不是整数类型,但您返回的是 int 类型。如果我们将两个整数相加可能会导致超过 int 类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-27
        • 1970-01-01
        • 1970-01-01
        • 2021-11-02
        • 1970-01-01
        • 2016-05-23
        • 2020-02-14
        相关资源
        最近更新 更多