C中32位数的乘法 [英] Multiplication of 32 bits numbers in C

查看:104
本文介绍了C中32位数的乘法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C中尝试两个乘以矩阵,我无法理解为什么我得到这些结果...

(我正在尝试编写一个程序,将两个32位数字相乘以便导入系统只有32位寄存器)



B = [15643 54056 -33591

24466 26823 54561

58751 -25563 -13777]



我想这样做: Btranspose * B

I am trying two multiply to matrices in C and I cant understand why I get these results...
(I am trying write a program that multiplies two 32 bits numbers to be imported on a system that has only 32 bit registers)

B = [ 15643 54056 -33591
24466 26823 54561
58751 -25563 -13777 ]

I want to do : Btranspose * B

#define LOW_WORD(x)  (((x) << 16) >> 16) 
#define HIGH_WORD(x) ((x) >> 16)
#define ABS(x) (((x) >= 0) ? (x) : -(x))
#define SIGN(x) (((x) >= 0) ? 1 : -1)
#define UNSIGNED_MULT(a, b) \
	(((LOW_WORD(a)  * LOW_WORD(b))  <<  0) + \
  	 ((LOW_WORD((a))  * HIGH_WORD((b))) << 16) + \
     ((HIGH_WORD((a)) * LOW_WORD((b)))  << 16) + \
     ((int64_t)(HIGH_WORD((a)) * HIGH_WORD((b))) << 32))
#define MULT(a, b)	(UNSIGNED_MULT(ABS((a)), ABS((b)))*SIGN((a))*SIGN((b)))

int c,d,k;
int64_t multmatrix[3][3];
int64_t sum64 = 0;
int32_t B, Btranspose;

for ( c = 0 ; c < 3 ; c++ ){
 for ( d = 0 ; d < 3 ; d++ ){
  for ( k = 0 ; k < 3 ; k++ ){
   sum64 = sum64 + MULT(Btranspose[c][k], B[k][d]);
   printf("\nthe MULT for k = %d is: %ld \n", k, MULT(Btranspose[c][k], B[k][d]));
   printf("\nthe sum for k = %d is: %ld \n", k, sum64);
   }
   multmatrix[c][d] = sum64;
   sum64 = 0;
  }
}





我的输出低于put错误,我注意到错误是什么时候是将第3个元素(58751 * 58751)乘以k = 2.

我认为不会溢出因为58751 ^ 2需要少于32位。



My output is below put that is wrong and I notice that the mistake is when is multiplying the 3rd element (58751 * 58751) for k=2.
I think is not overflowing because 58751^2 needs less than 32bits.

the MULT for k = 0 is: 244703449

the sum for k = 0 is: 244703449

the MULT for k = 1 is: 598585156

the sum for k = 1 is: 843288605

the MULT for k = 2 is: 46036225   // this is WRONG!!!

the sum for k = 2 is: 889324830
.
.
.
.
the MULT for k = 2 is: 189805729

the sum for k = 2 is: 1330739379


multmatrix

889324830   650114833   324678230
650114833   1504730698   -308929574
324678230   -308929574   1330739379





为什么矩阵的乘法错误?

我应该更改上面的代码,以便两个矩阵的乘法将是溢出的?



Why is the multiplication of the matrix wrong??
What should I change the above code so that the multiplication of two matrices will be overflow-proof??

推荐答案

FranxCDOFranx写道:
FranxCDOFranx wrote:



嘿谢尔盖,如果你指的是我是的我不明白,因为我是这个领域的初学者。我正在尝试调试并找到错误乘法的原因。如果你想更具体地解决我应该如何调试和修复算法的问题,请做。谢谢。


Hey Sergey, if you are referring to me yes I didn't not understand as I am a beginner in this field. I am trying to debug and find the reason for the wrong multiplication. If you want to be more specific to the problem as to how I should debug and fix the algorithm please do. Thank you.

作为初学者,没有为不调试提供借口;只是一开始你需要调试更多,然后获得更多经验。



请参阅我对这个问题的评论。让我继续对于大多数错误,调试过程显示收敛的属性( https:/ /en.wikipedia.org/wiki/Series_%28mathematics%29#Absolute_convergence [ ^ ]):在下一步之后,您将更接近找出错误,您可以在有限数量(实际上,少量步骤)中执行此操作。您的任务是构建一个融合调试步骤的过程。我已经在我对这个问题的一个评论中描述了假设和确认这个概念。



更多提示:



当你停在某个断点时,你总能找到它来自使用Debug窗口call stack的地方。调试不正确的递归时最有用。在所有情况下,要理解一般的编程,您需要了解调用堆栈如何工作以提供通常的调用机制,参数传递和返回,以及堆栈变量和异常的性质。

In 假设方法,你可以暂时禁用一些或所有断点,而不是删除它们,因为它很可能最终你必须重新开始。在监视窗口中,您可以使用显示其引用标识的标记来标记对象(您只能使用 System.Object.ReferenceEquals 在代码中执行相同操作,但它更有用在调试期间。



当然扫描所有调试窗口的所有菜单并全部尝试。这将花费最少的时间,但将非常有用,并很快得到回报。查看所有这些操作的帮助页面。



-SA

Being the beginner does not provide an excuse for not debugging; it's just that at first you have to debug more then when you get more experience.

Please see my comment to the question. Let me continue. For most bugs, the process of debugging shows the property of convergence (https://en.wikipedia.org/wiki/Series_%28mathematics%29#Absolute_convergence[^]): after next step, you come closer to figuring out of the bug, which you can do in a finite number (practically, small number of steps). Your task is to build a process of converging debugging step. I already described the idea "hypothesis and confirmation" steps in one of my comments to the question.

Some more hints:

When you stopped at some break point, you can always find where it comes from using Debug window "call stack". It is most useful when you debug incorrect recursion. In all cases, to understand programming in general, you need to understand how call stack works to provide the usual mechanism of calls, parameter passing and return, and also the nature of stack variables and exception.
In "hypothesis" approach, you can temporary disable some or all break point instead of removing them, as it's very likely that eventually you have to start over. In the watch window, you can mark the object with the tag revealing its referential identity (you can do the same in code only using System.Object.ReferenceEquals, but it's more useful during debugging).

Certainly scan all menus of all debug windows and try it all out. It will take minimal time but will be extremely useful and pay off very soon. Look at help pages on all those operations.

—SA


作为phil.o和谢尔盖·亚历山德罗维奇·克鲁科夫在上面的状态,问题在于数字的代表性。以下代码有效。



As phil.o and Sergey Alexandrovich Kryukov state above, the problem was with the representation of the numbers. The below code works.

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

#define LOW_WORD(x)  (((x) << 16) >> 16) 
#define HIGH_WORD(x) ((x) >> 16)
#define ABS(x) (((x) >= 0) ? (x) : -(x))
#define SIGN(x) (((x) >= 0) ? 1 : -1)

#define UNSIGNED_MULT(a, b) \
    (((LOW_WORD(a)  * LOW_WORD(b))  <<  0) + \
     (((int64_t)((LOW_WORD((a)) * HIGH_WORD((b))) + (HIGH_WORD((a)) * LOW_WORD((b))))) << 16) + \
     ((int64_t)(HIGH_WORD((a)) * HIGH_WORD((b))) << 32))

#define MULT(a, b)  (UNSIGNED_MULT(ABS((a)), ABS((b))) * SIGN((a)) * SIGN((b)))


int main()
{
    int c,d,k;
    int64_t multmatrix[3][3];
    int64_t sum64 = 0;
    int32_t Btranspose[3][3] = {{15643, 24466, 58751},
                               {54056, 26823, -25563},
                               {-33591, 54561, -13777}};
    int32_t B[3][3] = {{15643, 54056, -33591},
                      {24466, 26823, 54561},
                      {58751, -25563, -13777}};

    for ( c = 0 ; c < 3 ; c++ ){
        for ( d = 0 ; d < 3 ; d++ ){
            for ( k = 0 ; k < 3 ; k++ ){
                sum64 = sum64 + MULT(Btranspose[c][k], B[k][d]);
                printf("\n the MULT for k = %d is: %ld \n", k, MULT(Btranspose[c][k], B[k][d]));
                printf("\n the sum for k = %d is: %ld \n", k, sum64);
            }
            multmatrix[c][d] = sum64;
            sum64 = 0;
        }
    }       

    printf("\n\n multmatrix \n");
    for( c = 0 ; c < 3; c++ ){
        printf("\n");
        for( d = 0 ; d < 3 ; d++ ){
            printf(" %ld  ", multmatrix[c][d]);
        }
    }
    return 0;
}</math.h></stdbool.h></stdlib.h></stdio.h>


这篇关于C中32位数的乘法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆