两个整数相乘的结果一定正确吗?

问题:在我们编写程序时 ,经常需要进行各种计算,例如:将两个int型整数的乘积,赋值给一个 long 型变量,请问这种计算结果一定正确吗?

当为一个 long 型变量赋值一个整数常量时,如果这个整数超过了 int 的取值范围,程序就会出现编译错误,但是有一种情况程序是不会出错的,就是将多个 int 型数据进行算术运算的结果 赋值 给 long 型变量,即使这个运算结果超出了 int 的范围,程序也不会出现编译错误。

说明:一个 Int 在内存中占用 4 个字节的存储空间,其取值范围是 -2147483648 ~ 2147483647 之间的整数,而一个 long 型在内存中占用 8 个字节,取值范围是 -9223372036854775808 ~ 9223372036854775807 之间的整数。

// 出现编译错误
long num1 = 2147483648;

解释:上面的示例 为 long 型变量 num1 赋值 2147483648,由于数值超出了 int 的取值范围,所以程序出现了编译错误,为了能够正确的赋值,需要在 2147483648 后面加 上 小写字母 l 或者是 大写字母 L,这样示例就不会出错了。

// 能够通过编译,结果错误
long num2 = 2147483647 * 10;
System.out.println(num2);// -10

解释:上面示例输出为 -10,并不是我们期待的结果 21474836470,这个是由于参加计算的两个整数都没有超出 int 的取值范围 ,所以编译不会报错;结果错误是由于两个数的乘积时,是以 int 型数据进行计算的,所以计算结果也应该是 int 型,由于结果超出了 int 的取值范围,所以程序发生了 溢出,但是程序会保留这个溢出的结果,所以输出了 -10;

// 既能通过编译,结果又正确
long num4 = 2147483647L * 10;
System.out.println(num4);

解释:上面示例输出为 21474836470,这正是我们期望的结果。这是由于参加计算的两个整数中第一个整数后添加了大写字母 L,这样表示要进行的运算是按长整数进行的,所以程序不会发生溢出,因此可以计算出正确的结果。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是用C语言实现的程序: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LEN 100000 void strrev(char* s) { int len = strlen(s); for (int i = 0; i < len / 2; i++) { char temp = s[i]; s[i] = s[len - 1 - i]; s[len - 1 - i] = temp; } } void padding(char* s, int len) { int cur_len = strlen(s); for (int i = 0; i < len - cur_len; i++) { strrev(s); strcat(s, "0"); strrev(s); } } void karatsuba(char* x, char* y, char* result) { int len = strlen(x); if (len == 1) { int xy = (x[0] - '0') * (y[0] - '0'); sprintf(result, "%d", xy); } else { int m = len / 2; char x1[MAX_LEN]; char x2[MAX_LEN]; char y1[MAX_LEN]; char y2[MAX_LEN]; char z0[MAX_LEN]; char z1[MAX_LEN]; char z2[MAX_LEN]; char temp1[MAX_LEN]; char temp2[MAX_LEN]; char temp3[MAX_LEN]; strncpy(x1, x, m); x1[m] = '\0'; strncpy(x2, x + m, len - m); x2[len - m] = '\0'; strncpy(y1, y, m); y1[m] = '\0'; strncpy(y2, y + m, len - m); y2[len - m] = '\0'; karatsuba(x1, y1, z0); karatsuba(x2, y2, z2); int x1x2_len = strlen(x1) + strlen(x2); int y1y2_len = strlen(y1) + strlen(y2); padding(x1, x1x2_len); padding(x2, x1x2_len); padding(y1, y1y2_len); padding(y2, y1y2_len); sprintf(temp1, "%d", atoi(x1) + atoi(x2)); sprintf(temp2, "%d", atoi(y1) + atoi(y2)); karatsuba(temp1, temp2, z1); sprintf(temp1, "%d", atoi(z1) - atoi(z0) - atoi(z2)); padding(temp1, m); strcat(z0, temp1); padding(z0, 2 * m); strcat(z0, z2); strcpy(result, z0); } } int main() { char x[MAX_LEN]; char y[MAX_LEN]; char result[MAX_LEN * 2]; printf("请输入两个长度大于10的大整数:\n"); scanf("%s %s", x, y); karatsuba(x, y, result); printf("karatsuba乘法的结果为:%s\n", result); printf("验证结果的正确性:\n"); long long x_num = atoll(x); long long y_num = atoll(y); long long result_num = atoll(result); if (x_num * y_num == result_num) { printf("结果正确\n"); } else { printf("结果错误\n"); } return 0; } ``` 程序中用到了strrev函数将字符串反转、padding函数将短字符串前面补0、karatsuba函数进行高精度乘法,main函数用于输入两个整数并进行karatsuba乘法,最后验证结果的正确性。 注意,如果输入的两个整数长度不足10位,程序可能会出现意料之外的错误,因此需要确保输入的两个整数长度大于10位。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值