unsigned long int给出整数溢出

时间:2014-08-04 13:48:28

标签: c integer-overflow unsigned-long-long-int

我正在尝试在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;
}

2 个答案:

答案 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