unsigned long int给出整数溢出

Pra*_*ngh 0 c integer-overflow unsigned-long-long-int

我试图在c中创建一个程序来解决数独游戏,其中我试图在无符号长整数变量中存储一个等于2*3*5*7*11*13*17*19*23*29的数字.在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;
}
Run Code Online (Sandbox Code Playgroud)

maf*_*fso 6

unsigned long int full=29*23*19*17*13*11*7*5*3*2;
Run Code Online (Sandbox Code Playgroud)

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

第二,也是更重要的:RHS的类型int可以溢出(术语溢出不用于无符号整数,既不是C标准也不是gcc消息,它被称为环绕(或截断,在gcc警告中) ),它总是有明确定义的语义),实际上在大多数系统上都这样做.使用

unsigned long long full = 29ull*23*19*17*13*11*7*5*3*2;
Run Code Online (Sandbox Code Playgroud)

代替.

HTH

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

  • 最后一个音符+½(从零开始舍入) (3认同)