2015-09-03 10 views
0

Я пытаюсь написать реализацию «BigInteger». BigInteger - это массив целых чисел без знака.Сравнение целых чисел без знака

BigInteger_1 [0] ... BigInteger_1 [15]; 

Я пытаюсь выполнить добавление двух BigInteger's.

using System; 

namespace BigInt { 

    class MainClass { 

     static int MAX_SIZE = 16; 

     public static void Main() { 

      // First BigInteger 

      uint[] BigInteger_1 = new uint[MAX_SIZE]; 

      BigInteger_1 [15] = 0xfffffffe; 

      // Second BigInteger 

      uint[] BigInteger_2 = new uint[MAX_SIZE]; 

      BigInteger_2 [15] = 0x00000002; 

      // Third BigInteger 

      uint[] BigInteger_3 = new uint[MAX_SIZE]; 

      // Perform an addition 

      BigInteger_3 = BigInteger_Add (BigInteger_1, BigInteger_2); 

      int i; 

      // Print BigInteger_1 

      for (i = 1; i < MAX_SIZE; i ++) { 

       Console.Write ("{0:x8}", BigInteger_1 [i]); 

      } 

      Console.WriteLine(); 

      // Print BigInteger_2 

      for (i = 1; i < MAX_SIZE; i ++) { 

       Console.Write ("{0:x8}", BigInteger_2 [i]); 

      } 

      Console.WriteLine(); 

      // Print BigInteger_3 

      for (i = 1; i < MAX_SIZE; i ++) { 

       Console.Write ("{0:x8}", BigInteger_3 [i]); 

      } 

      Console.WriteLine(); 

     } 

     public static uint[] BigInteger_Add (

      uint[] BigInteger_1, 

      uint[] BigInteger_2 

      ) { 

      uint[] BigInteger_3 = new uint[MAX_SIZE]; 

      uint BigInteger_Carry = 0x00000000; 

      uint BigInteger_Limit = 0xffffffff; 

      int i; 

      // Loop through all integers 

      for (i = 1; i < MAX_SIZE; i ++) { 

       if (BigInteger_1 [i] + BigInteger_2 [i] >= BigInteger_Limit) { 

        Console.WriteLine ("Check {0} >= {1}", BigInteger_1 [i] + BigInteger_2 [i], BigInteger_Limit); 

        BigInteger_Carry = (BigInteger_1 [i] + BigInteger_2 [i]) - BigInteger_Limit; 

        BigInteger_3 [i] = BigInteger_Limit; 

       } else { 

        Console.WriteLine ("Check {0} < {1}", BigInteger_1 [i] + BigInteger_2 [i], BigInteger_Limit); 

        BigInteger_3 [i] = BigInteger_1 [i] + BigInteger_2 [i]; 

        BigInteger_Carry = 0x00000000; 

       } 

      } 

      if (BigInteger_Carry != 0x00000000) { 

       BigInteger_3 [i] = BigInteger_Carry; 

      } 

      return BigInteger_3; 

     } 

    } 

} 

Когда я установил переменные для:

// First BigInteger 
BigInteger_1 [15] = 0xfffffffe; 

// Second BigInteger 
BigInteger_2 [15] = 0x00000001; 

Тогда после выполнения я получаю этот выход (прокручивать направо):

Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 4294967295 >= 4294967295 
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffe 
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff 

который выглядит правильно. Но когда я создал переменные:

// First BigInteger 
BigInteger_1 [15] = 0xfffffffe; 

// Second BigInteger 
BigInteger_2 [15] = 0x00000002; 

Я получаю это (прокрутить еще раз):

Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
Check 0 < 4294967295 
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffe 
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 

Так что я не могу сделать сравнение суммы двух целых чисел и максимальное значение, если сумма больше максимального значения. Что я могу (и должен) делать в этой ситуации?

+1

При добавлении двух 'значения uint', которые приводят к чему-то большему, чем' uint.MaxValue' это усечение и, следовательно, привести в значение меньше, чем 'uint.MaxValue'. Фактически по определению значение 'uint' не может превышать' uint.MaxValue'. Чтобы избежать усечения, вы можете отбросить «улунг». – juharr

+0

@juharr Спасибо, я буду использовать ulong для хранения суммы. – Kechup

ответ

1

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

Один неэффективный способ выполнить то, что вы пытаетесь сделать, чтобы сохранить в массиве BitInteger дополнительное целое число, которое вы можете внутренне поддерживать больше, чем точность Max_Size.

+0

Спасибо за объяснение! Поскольку @juharr сказал, что я могу использовать ulong для хранения суммы, возможно, это простой способ работать с ней. – Kechup

1

Вы пытаетесь проверить, если a + b > uint.MaxValue, который не работает, когда a + b переполнение.

Решение 1: bool carry = a > uint.MaxValue - b;

Решение 2: var result = a + b; bool carry = result < a || result < b;

+0

Спасибо, Иван! Я попытаюсь использовать это тоже. – Kechup

Смежные вопросы