我正在尝试在c中创建一个解决数独游戏的程序,其中我试图在无符号中存储一个等于2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 29的数字long int变量。 在32位Ubuntu机器上使用boath gcc和g ++进行编译时,我收到整数溢出错误。
请帮我存储和使用此号码,或建议替代方案。
我将整个代码包括在内。
#include <stdio.h>
#include <stdlib.h>
int main() {
int sudoku[9][9] = {2, 8, 0, 0, 0, 3, 0, 0, 0, // 0 is used to denote blank
4, 7, 0, 0, 8, 6, 0, 9, 1, 0, 0, 5, 0, 9, 0, 2, 3, 0,
0, 9, 0, 5, 2, 0, 4, 8, 6, 5, 0, 0, 0, 0, 0, 0, 0, 3,
8, 6, 1, 0, 7, 4, 0, 5, 0, 0, 3, 4, 0, 1, 0, 8, 0, 0,
7, 5, 0, 8, 3, 0, 0, 2, 4, 0, 0, 0, 6, 0, 0, 0, 7, 9};
unsigned long int ref[9][9];
int solved = 0;
int i, j, k;
unsigned long int full = 29 * 23 * 19 * 17 * 13 * 11 * 7 * 5 * 3 * 2;
int key = 0;
printf("%lu", full);
for (i = 0; i <= 9; i++) {
for (j = 0; j <= 9; j++) {
switch (sudoku[i][j]) {
case 1:
sudoku[i][j] = 2;
break;
case 2:
sudoku[i][j] = 3;
break;
case 3:
sudoku[i][j] = 5;
break;
case 4:
sudoku[i][j] = 7;
break;
case 5:
sudoku[i][j] = 11;
break;
case 6:
sudoku[i][j] = 13;
break;
case 7:
sudoku[i][j] = 17;
break;
case 8:
sudoku[i][j] = 19;
break;
case 9:
sudoku[i][j] = 23;
break;
case 0:
sudoku[i][j] = 29;
break;
default:
printf("\n Error in input");
break;
}
}
}
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
ref[i][j] = 29;
}
}
while (!solved) {
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
if (sudoku[i][j] != 29) {
for (k = 0; k < 9; k++) {
if (k != j) {
if (ref[i][k] % sudoku[i][j] != 0 &&
sudoku[i][k] == 29) {
ref[i][k] = ref[i][k] * sudoku[i][j];
}
}
}
for (k = 0; k < 9; k++) {
if (k != i) {
if (ref[k][j] % sudoku[i][j] != 0 &&
sudoku[k][j] == 29) {
ref[k][j] = ref[k][j] * sudoku[i][j];
}
}
}
}
}
}
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
if (ref[i][j] == full / 2 && sudoku[i][j] == 29) {
sudoku[i][j] = 2;
}
if (ref[i][j] == full / 3 && sudoku[i][j] == 31) {
sudoku[i][j] = 3;
}
if (ref[i][j] == full / 5 && sudoku[i][j] == 31) {
sudoku[i][j] = 5;
}
if (ref[i][j] == full / 7 && sudoku[i][j] == 31) {
sudoku[i][j] = 7;
}
if (ref[i][j] == full / 11 && sudoku[i][j] == 31) {
sudoku[i][j] = 11;
}
if (ref[i][j] == full / 13 && sudoku[i][j] == 31) {
sudoku[i][j] = 13;
}
if (ref[i][j] == full / 17 && sudoku[i][j] == 31) {
sudoku[i][j] = 17;
}
if (ref[i][j] == full / 19 && sudoku[i][j] == 31) {
sudoku[i][j] = 19;
}
if (ref[i][j] == full / 23 && sudoku[i][j] == 31) {
sudoku[i][j] = 23;
}
}
}
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
if (sudoku[i][j] == 29) {
key = 1;
}
}
}
if (key == 0) {
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
switch (sudoku[i][j]) {
case 2:
sudoku[i][j] = 1;
break;
case 3:
sudoku[i][j] = 2;
break;
case 5:
sudoku[i][j] = 3;
break;
case 7:
sudoku[i][j] = 4;
break;
case 11:
sudoku[i][j] = 5;
break;
case 13:
sudoku[i][j] = 6;
break;
case 17:
sudoku[i][j] = 7;
break;
case 19:
sudoku[i][j] = 8;
break;
case 23:
sudoku[i][j] = 9;
break;
}
printf("%d ", sudoku[i][j]);
}
printf("\n");
}
solved = 1;
}
else {
key = 0;
}
}
return 0;
}
答案 0 :(得分:6)
unsigned long int full=29*23*19*17*13*11*7*5*3*2;
两个问题:首先,乘法的算术结果(6469693230)占用33位,而unsigned long
可能只有32位。unsigned long long
保证至少有64位。 / p>
其次,更重要的是:RHS的类型是int
,它可以溢出(术语溢出不是用于无符号整数,既不是C标准也不是gcc消息,它&# 39; s称为环绕(或截断,在gcc警告中),它总是有明确定义的语义),实际上在大多数系统中都这样做。使用
unsigned long long full = 29ull*23*19*17*13*11*7*5*3*2;
代替。
HTH
最后一点:请不要提供与您的实际问题无关的代码。
答案 1 :(得分:0)
您可以使用更宽的类型,例如long long或float