Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перевод кода с С++ на C#, Деление длииных чисел 
:(
    Опции темы
yarus88
Дата 16.4.2009, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 17.4.2008

Репутация: нет
Всего: нет



Не получается правильно перевести код с С++ на C#

Вот есть деление длинного числа на длинное на С++ 
Код

// Q = A/B, R=A%B 
void Div(const BigInt &A, BigInt &B, BigInt &Q, BigInt &R) { 
 // Вырожденный случай 1. Делитель больше делимого. 
  if ( A.Size < B.Size ) {   
  Q.zero(); 
  R=A; 
  return; 
 } 
// Вырожденный случай 2. Делитель – число базового типа. 
  if ( B.Size == 1) {    
    SDiv ( A, B.Coef[0], Q, R.Coef[0]); 
  R.Size = 1; 
  return; 
 } 
  // Создать временный массив U, равный A 
 // Максимальный размер U на цифру больше A, с учетом  
 // возможного удлинения A при нормализации 
 BigInt U(A.Size+1); U = A; U.Coef[A.Size]=0;  
 
// Указатели для быстрого доступа 
 short *b=B.Coef, *u=U.Coef, *q=Q.Coef; 
  
long n=B.Size, m=U.Size-B.Size; 
 long uJ, vJ, i;     
 long temp1, temp2, temp; 
short scale;   // коэффициент нормализации 
 short qGuess, r;            // догадка для частного и соответствующий остаток 
 short borrow, carry;   // переносы 
// Нормализация 
 scale = BASE / ( b[n-1] + 1 );  
 if (scale > 1) {     
   SMul (U, scale, U); 
   SMul (B, scale, B); 
 } 
// Главный цикл шагов деления. Каждая итерация дает очередную цифру частного. 
// vJ - текущий сдвиг B относительно U, используемый при вычитании, 
// по совместительству - индекс очередной цифры частного. 
// uJ – индекс текущей цифры U 
 for (vJ = m, uJ=n+vJ; vJ>=0; --vJ, --uJ) { 
   qGuess = (u[uJ]*BASE + u[uJ-1]) / b[n-1]; 
   r = (u[uJ]*BASE + u[uJ-1]) % b[n-1]; 
  // Пока не будут выполнены условия (2) уменьшать частное. 
   while ( r < BASE) {  
   temp2 = b[n-2]*qGuess; 
     temp1 = r*BASE + u[uJ-2]; 
     if ( (temp2 > temp1) || (qGuess==BASE) ) { 
    // условия не выполнены, уменьшить qGuess  
    // и досчитать новый остаток 
    --qGuess; 
    r += b[n-1]; 
   } else break; 
  } 
 // Теперь qGuess - правильное частное или на единицу больше q   
 // Вычесть делитель B, умноженный на qGuess из делимого U, 
 // начиная с позиции vJ+i 
 carry = 0; borrow = 0;  
 short *uShift = u + vJ; 
 // цикл по цифрам B 
 for (i=0; i<n;i++) { 
  // получить в temp цифру произведения B*qGuess 
   temp1 = b[i]*qGuess + carry;   
   carry = temp1 / BASE; 
   temp1 -= carry*BASE;        
  // Сразу же вычесть из U 
   temp2 = uShift[i] - temp1 + borrow;   
   if (temp2 < 0) { 
   uShift[i] = temp2 + BASE; 
   borrow = -1; 
  } else { 
   uShift[i] = temp2; 
   borrow = 0; 
  } 
 } 
// возможно, умноженое на qGuess число B удлинилось. 
 // Если это так, то после умножения остался  
// неиспользованный перенос carry. Вычесть и его тоже. 
    temp2 = uShift[i] - carry + borrow; 
    if (temp2 < 0) { 
      uShift[i] = temp2 + BASE; 
   borrow = -1; 
  } else { 
   uShift[i] = temp2; 
   borrow = 0; 
  } 
   
 
  // Прошло ли вычитание нормально ? 
    if (borrow == 0) {    // Да, частное угадано правильно 
   q[vJ] = qGuess;  
 
  } else { // Нет, последний перенос при вычитании borrow = -1, 
    // значит, qGuess на единицу больше истинного частного 
   q[vJ] = qGuess-1; 
  // добавить одно, вычтенное сверх необходимого B к U 
  carry = 0; 
   for (i=0; i<n; i++) { 
     temp = uShift[i] + b[i] + carry; 
   if (temp >= BASE) { 
    uShift[i] = temp - BASE; 
    carry = 1; 
   } else { 
    uShift[i] = temp; 
    carry = 0; 
   } 
  } 
   uShift[i] = uShift[i] + carry - BASE; 
 } 
 // Обновим размер U, который после вычитания мог уменьшиться 
 i = U.Size-1; 
 while ( (i>0) && (u[i]==0) ) i--; 
 U.Size = i+1; 
 } 
 // Деление завершено ! 
 
 // Размер частного равен m+1, но, возможно, первая цифра - ноль. 
  while ( (m>0) && (q[m]==0) ) m--; 
  Q.Size = m+1; 
  
 // Если происходило домножение на нормализующий множитель –  
 // разделить на него. То, что осталось от U – остаток. 
  if (scale > 1) { 
  short junk;  // почему-то остаток junk всегда будет равен нулю… 
    SDiv ( B, scale, B, junk); 
    SDiv ( U, scale, R, junk); 
  } else R=U;   


Не получается правильно на C# это сделать...
у меня есть класс BigInt
Код

static int BASE = 10;
        public class BigInt
        {
            public int len; //длинна числа
            public int[] digs = new int[1000];
        }


есть функции SMul (умножение длинного на короткое) и SDiv (деление длинного на короткое)
Код

static void SMul(BigInt NumberA, int NumberB, BigInt Answer)
        {
            int i, temp;
            int carry = 0;
            for (i = 0; i < NumberA.len; i++)
            {
                temp = NumberA.digs[i] * NumberB + carry;
                carry = temp / BASE;
                Answer.digs[i] = temp - carry * BASE;
            }
            if (carry == 1)
            {
                Answer.digs[i] = carry;
                i++;
            }
            Answer.len = i;
        }


Код

static void SDiv(BigInt NumberA, int NumberB, BigInt Answer, BigInt Rest)
        {
            int i, temp;
            Rest.digs[0] = 0;
            Rest.len = 1;            
            for (i = NumberA.len - 1; i >= 0; i--)
            {
                temp = Rest.digs[0] * BASE + NumberA.digs[i];
                Answer.digs[i] = temp / NumberB;
                if ((Answer.digs[i] != 0) && (Answer.len < i))
                {
                    Answer.len = i + 1;
                }
                Rest.digs[0] = temp - Answer.digs[i] * NumberB;                
            }            
        }


Помогите с делением длинного на длинное.. smile 3 день парюсь никак не получится!!!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0753 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.