0

我正在尝试在 c 中创建一个程序来解决数独难题,其中我试图将等于 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 29 的数字存储在 unsigned 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;
}
4

2 回答 2

6
unsigned long int full=29*23*19*17*13*11*7*5*3*2;

两个问题:首先,乘法的算术结果(6469693230)占用33位,而anunsigned long可能只有32位。anunsigned long long保证至少有64位。

其次,更重要的是:RHS 的类型是int,它可以溢出(术语溢出不用于无符号整数,既不是 C 标准也不是 gcc 消息,它被称为环绕(或截断,在 gcc 警告中) ),它始终具有明确定义的语义),实际上在大多数系统上都是如此。采用

unsigned long long full = 29ull*23*19*17*13*11*7*5*3*2;

反而。

高温高压

最后一点:请不要提供太多与您的实际问题无关的代码。

于 2014-08-04T13:56:09.610 回答
0

您可以使用更宽的类型,例如 long long 或 float

于 2014-08-04T13:58:54.393 回答