2015-04-08 5 views
1

Когда рекурсивная функция срабатывает и возвращает результаты вверх, происходит сбой из-за переполнения данных. Как я могу использовать этот алгоритм D & C и избежать этой проблемы?Как избежать переполнения большого числа с помощью рекурсивной функции (C#, D & C)

static long long zarb(long a, long b, int n) 
{ 
     Int64 w, x, y, z; 
     int s; 

     if (a == 0 || b == 0) 
      return 0; 

     if (n <25) 
      return a * b; 
     else 
     { 
      s = n/2; 
      long p = power(2, s); 
      w = a/p; 
      x = a % p; 
      y = b/p; 
      z = b % p; 
      return (zarb(w, y, n/2) * power(2, 2 * s) + p * (zarb(w, z, n/2) + zarb(x, y, n/2)) + zarb(x, y, n/2)); 
     } 
} 

static long power(int x, int y) 
{ 
     long sum = 1; 

     if (y == 0) 
      return 0; 

     for (int i = 1; i <= y; i++) 
      sum = sum * x; 

     return sum; 
} 
+0

Переполнение длинного типа данных? Какое исключение вы получаете? Это 'OverflowException' или' StackOverflowException'? –

+0

Итак, что именно вы хотите, чтобы поведение было? Предотвращать его от сбоев легко, но как вы хотите, чтобы он обрабатывался? –

+0

'static long long' это C#, а не C. Здесь нет' long long'. И лучше, если вы не будете смешивать 'Int64' и' long'. Это одно и то же, но это дает плохое чувство читателю. – xanatos

ответ

2

Нет проблем с кодом, он работает для определенного диапазона входов. Если вам нужно ввести значения, которые приведут к значениям из диапазона в int64, попробуйте другой тип. System.Numerics встроена в .NET и имеет тип BigInteger, который претендует на «произвольно большое целое число, теоретическое значение которого не имеет верхних или нижних границ». Это может занять некоторое время, чтобы работать с этими большими ценными входами, но это должно быть хорошо.

https://msdn.microsoft.com/en-us/library/system.numerics.biginteger%28v=vs.110%29.aspx