По модулю очень большой int C # - PullRequest
1 голос
/ 14 апреля 2011

У меня проблема с модулем от int, который имеет 31 символ.Кажется, ошибка на
Int64 convertedNumber = Int64.Parse(mergedNumber); с Value was either too large or too small for an Int64. (Overflow Exception).Как это исправить, чтобы по модулю не вышло?

class GeneratorRachunkow {
    private static string numerRozliczeniowyBanku = "11111155"; // 8 chars
    private static string identyfikatorNumeruRachunku = "7244"; // 4 chars
    private static string stalaBanku = "562100"; // 6 chars

    public static string generator(string pesel, string varKlientID) {      
        string peselSubstring = pesel.Substring(pesel.Length - 5); // 5 chars (from the end of the string);
        string toAttach = varKlientID + peselSubstring;
        string indywidualnyNumerRachunku = string.Format("{0}", toAttach.ToString().PadLeft(13, '0')); // merging pesel with klient id and adding 0 to the begining to match 13 chars
        string mergedNumber = numerRozliczeniowyBanku + identyfikatorNumeruRachunku + indywidualnyNumerRachunku + stalaBanku; // merging everything -> 31 chars
        Int64 convertedNumber = Int64.Parse(mergedNumber);
        Int64 modulo = MathMod(convertedNumber, 97);

        Int64 wynik = 98 - modulo;
        string wynikString = string.Format("{0}", wynik.ToString().PadLeft(2, '0')); // must be 2 chars
        indywidualnyNumerRachunku = wynikString + numerRozliczeniowyBanku + identyfikatorNumeruRachunku + indywidualnyNumerRachunku; 

        return indywidualnyNumerRachunku;
    }
    private static Int64 MathMod(Int64 a, Int64 b) {
        return (Math.Abs(a * b) + a) % b;
    }

}

Ответы [ 4 ]

5 голосов
/ 14 апреля 2011

Максимальное значение для Int64 составляет 9223372036854775807 (19 символов при печати). Вы, вероятно, захотите использовать BigInteger (который был представлен в .NET 4):

public static string generator(string pesel, string varKlientID) { 
    // I have cut some code here to keep it short
    BigInteger convertedNumber;
    if (BigInteger.TryParse(mergedNumber , out convertedNumber))
    {
        BigInteger modulo = convertedNumber % 97;           
        // The rest of the method goes here...
    }
    else
    {
        // string could not be parsed to BigInteger; handle gracefully
    }

}

private static BigInteger MathMod(BigInteger a, BigInteger b)
{
    return (BigInteger.Abs(a * b) + a) % b;
}
2 голосов
/ 14 апреля 2011

Попробуйте эту функцию вместо "MathMod":

    static int ModString(string x, int y)
    {
        if (x.Length == 0)
            return 0;
        string x2 = x.Substring(0,x.Length - 1); // first digits
        int x3 = int.Parse(x.Substring(x.Length - 1));   // last digit
        return (ModString(x2, y) * 10 + x3) % y;
    }

(поскольку все ваши числа положительны, нет смысла использовать Math.Abs, как в исходной функции MathMod).

Используйте это так:

modulo = ModString(mergedNumber,97);

Это должно работать со всеми версиями .NET начиная с версии 1.1, без использования BigInteger.

2 голосов
/ 14 апреля 2011

Int64.MaxValue - 9 223 372 036 854 775 807, то есть 19 символов. Так что вы просто не можете с этим справиться. Я предлагаю посмотреть на этот вопрос для работы с большими числами.

1 голос
/ 14 апреля 2011

Ответ, который вы ищете, демонстрируется здесь . Он включает в себя различные способы расчета модуля для огромных чисел. Я использовал методы, аналогичные описанным здесь для номеров международных банковских счетов.

Прямая ссылка на кого-то, у кого есть метод вставки копии: здесь .

...