Длинная арифметика си шарп

Длинная арифметика

Здравствуйте,хочу сделать класс,аналог класса BigNumber (да я понимаю что есть уже готовый но просто хочу мозги размять), Пока остановился на методе умножения. Можете подкинуть пару идеи,как можно это получше сделать? Вот мои наработки.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
using System; using System.Collections.Generic; using System.Text.RegularExpressions; namespace BigNumber { public class BigNumber { private readonly int[] _digits; private readonly Regex _regEx = new Regex(@"^3+$"); public BigNumber(string x) { if (string.IsNullOrWhiteSpace(x)) throw new ArgumentNullException(nameof(x), "Исходная строка является пустой!"); if (!_regEx.IsMatch(x)) throw new ArgumentException("В исходной строке содержатся нечисловые элементы!", nameof(x)); x = Regex.Replace(x, @"^0+(?=\d+$)", "");//0000 превращается в 0 var arraySize = x.Length; _digits = new int[arraySize]; arraySize -= 1; for (var i = arraySize; i >= 0; i--) _digits[arraySize - i] = x[i] - '0'; } private BigNumber(int[] x) { _digits = new int[x.Length]; var arraySize = x.Length - 1; for (var i = arraySize; i >= 0; i--) _digits[arraySize - i] = x[i]; } public static BigNumber operator +(BigNumber a, BigNumber b) { var resultArraySize = a._digits.Length > b._digits.Length ? a._digits.Length : b._digits.Length; var resultArray = new int[resultArraySize]; var carry = 0; for (var i = 0; i  resultArraySize; i++) { var n1 = GetValue(a._digits, i); var n2 = GetValue(b._digits, i); var sum = carry + n1 + n2; carry = sum / 10; resultArray[i] = sum % 10; } if (carry > 0) { resultArraySize += 1; Array.Resize(ref resultArray, resultArraySize); resultArray[resultArraySize - 1] = carry; } return new BigNumber(resultArray); } public static BigNumber operator *(BigNumber a, BigNumber b) { var carry = 0; var ret = new Listint>(); for (var j = 0; j  b._digits.Length; j++) { for (var i = 0; i  a._digits.Length; i++) { var op = carry + GetValue(a._digits, i) * GetValue(b._digits, j); carry = op / 10; ret.Add(op % 10); } if (carry != 0) ret.Add(carry); } return new BigNumber(""); throw new NotImplementedException(); } private static int GetValue(int[] obj, int index) { return index  obj.Length - 1 ? obj[index] : 0; } public override string ToString() { return string.Concat(_digits); } } }

Источник

Длинная арифметика. Перевод массива байт в строку

Добрый день !
Прочитал много статей о длинной арифметики . Но озов так и не увидел (или не понял) .
Поставил себе задачу для изучения (понимания) .
Дано : число в 512 бит ( 64 байта ) записанное в виде массива байт .
Нужно : этот массив перегнать в строку с десятичным эквивалентом .

Перевод в 18 СС. Длинная арифметика
Здравствуйте. Столкнулась с такой проблемой, как переводом длинного числа из 10 СС в 18 СС. Длинные.

Перевод массива байт в строку и обратно
Здравсвуйте, в результате шифрования есть некоторая последовательность байт. Как преобразовать эту.

Длинная арифметика. Перевод из десятичной системы счисления в двоичную
требуется написать программу для перевода числа с количеством цифр >20 из десятичной системы.

Длинная арифметика, перевод чисел другие системы счисления
Добрый вечер программисты ,у меня есть один ,наверно сложный, вопрос, проблема вот в чем когда я.

Marchcat, в данной задаче все зависит от 2-ух факторов, а именно форма записи битов и байтов:
1) порядок байтов (слева направо или наоборот)
2) порядок битов (старший слева и младший справа или наоборот)
Рассмотрим на примере чисел 5 и 0
5 — это 00000101
0 — это 00000000
Если дана последовательность байтов

То в зависимости от вышеуказанных 2-ух факторов можно составить последовательность битов разными способами

00000000 00000101 00000000 10100000 00000101 00000000 10100000 00000000
byte[] byteArr = new byte[] { 0, 5 }; BitArray array = new BitArray(byteArr); // 00000000 10100000 - таков порядок битов в BitArray BigInteger integer = 0; for (int i = 0; i  array.Length; i++) integer += (array[i] ? 1 : 0) * (int)Math.Pow(2, i); Console.WriteLine(integer);

В данном примере можно увидеть что младший бит слева, старший бит справа. Порядок байтов остается неизменным, а биты меняются местами на 180 градусов (из за того, что младший бит слева).

В вашей задаче 512 бита (64 байта) все тоже самое.

BigInteger N = new BigInteger(byteArray); byte[] byteArray = N.ToByteArray(); string c = N.ToString();
byte[] a = {0x07 , 0x06}; int b = 0x07 * 0x100 + 0x06; string c = b.ToString();

С int можно и сдвигом загнать и вывести.
Но как перегнать 64 , 128 , 256 и тд. байт в десятичное значение и записать в string ?

ЦитатаСообщение от Marchcat Посмотреть сообщение

ЦитатаСообщение от Marchcat Посмотреть сообщение

ЦитатаСообщение от Marchcat Посмотреть сообщение

ЦитатаСообщение от Marchcat Посмотреть сообщение

ЦитатаСообщение от Marchcat Посмотреть сообщение

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Numerics; namespace BigIntegerToString { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void b_hex_to_dec_Click(object sender, EventArgs e) { //Забираем с формы BigInteger и превращаем его в массив байт string s_biginteger = r_biginteger.Text; s_biginteger = s_biginteger.Replace("0x", ""); s_biginteger = s_biginteger.Replace(" ", ""); s_biginteger = s_biginteger.Replace("\r", ""); s_biginteger = s_biginteger.Replace("\n", ""); int NumberChars = s_biginteger.Length; byte[] b_biginteger = new byte[NumberChars / 2]; for (int i = 0; i  NumberChars; i += 2) b_biginteger[i / 2] = Convert.ToByte(s_biginteger.Substring(i, 2), 16); //Делаем реверс индекса байт для конвертации в BigInteger byte[] byteArrayN = new byte[b_biginteger.Length + 1]; byteArrayN[byteArrayN.Length - 1] = 0x00; for (int k = 0; k  b_biginteger.Length; k++) { byteArrayN[k] = b_biginteger[b_biginteger.Length - 1 - k]; } //Создаем BigInteger BigInteger N = new BigInteger(byteArrayN); //Преобразуем в строку string a = N.ToString(); //Выводим значение в log log.AppendText(a + "\n"); } } }

Так допустим через System.Numeric я делаю перевод большого числа в виде массива байт в строку.

число:
12 45 AC 78 BF D7 18 92 FF 62 99 CE A3 D8 D6 94
A2 4E CB 3E 4C 40 66 00 02 0A E4 77 54 40 53 09
70 BC 4D 39 90 6B 69 E8 0E 2A 60 85 58 9C B3 C2
85 62 E0 32 63 E9 98 43 A6 99 54 36 DF 91 74 EB
74 97 01 41 E0 E8 0D 33 07 97 CE 5D E2 24 CD 9E
D2 39 87 48 BE 78 3C 90 7D F3 EE AA 73 59 E6 DF
09 68 03 82 26 88 49 49 72 62 13 1A AB 1F 3D CB
A2 4E CB 3E 4C 40 66 00 02 0A E4 77 54 40 53 09
получаем:
12831149183740727160260225246313054710046725315422110450517447320262107203652507 63175011354770245566189298557844083579775645030411267904255096432406978021104123 37478307539812905702783197044315937831629397739161869816356926614780741446723070 59951471141148841210115006592007156983548438215868449154004485690121

Добавлено через 42 секунды
А я хочу научиться этому переводу без BigInteger .

ЦитатаСообщение от Marchcat Посмотреть сообщение

Что за ненависть к типу данных? Как вы вообще собираетесь делать перевод числа, если вы даже не можете его записать в переменную ?

Marchcat, код взял здесь BigNumber
удалил все что мешало запустить, руками склеил байты в uint и всё работает

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
using System; using System.Globalization; class Program  public static ulong MakeUlong(uint uHi, uint uLo) { return ((ulong)uHi  32)  static String FormatBigInteger(uint[] value, String format, NumberFormatInfo info) { // First convert to base 10^9. const uint kuBase = 1000000000; // 10^9 const int kcchBase = 9; int cuSrc = value.Length; int cuMax; try { cuMax = checked(cuSrc * 10 / 9 + 2); } catch (OverflowException e) { throw new FormatException(); } uint[] rguDst = new uint[cuMax]; int cuDst = 0; for (int iuSrc = cuSrc; --iuSrc >= 0;) { uint uCarry = value[iuSrc]; for (int iuDst = 0; iuDst  cuDst; iuDst++) { //Contract.Assert(rguDst[iuDst] < kuBase);ulong uuRes = MakeUlong(rguDst[iuDst], uCarry); rguDst[iuDst] = (uint)(uuRes % kuBase); uCarry = (uint)(uuRes / kuBase); } if (uCarry != 0) { rguDst[cuDst++] = uCarry % kuBase; uCarry /= kuBase; if (uCarry != 0) rguDst[cuDst++] = uCarry; } } int cchMax; try { // Each uint contributes at most 9 digits to the decimal representation. cchMax = checked(cuDst * kcchBase); } catch (OverflowException e) { throw new FormatException(); } int rgchBufSize; try { // We'll pass the rgch buffer to native code, which is going to treat it like a string of digits, so it needs // to be null terminated. Let's ensure that we can allocate a buffer of that size. rgchBufSize = checked(cchMax + 1); } catch (OverflowException e) { throw new FormatException(); } char[] rgch = new char[rgchBufSize]; int ichDst = cchMax; for (int iuDst = 0; iuDst  cuDst - 1; iuDst++) { uint uDig = rguDst[iuDst]; //Contract.Assert(uDig < kuBase);for (int cch = kcchBase; --cch >= 0;) { rgch[--ichDst] = (char)('0' + uDig % 10); uDig /= 10; } } for (uint uDig = rguDst[cuDst - 1]; uDig != 0;) { rgch[--ichDst] = (char)('0' + uDig % 10); uDig /= 10; } // Format Round-trip decimal // This format is supported for integral types only. The number is converted to a string of // decimal digits (0-9), prefixed by a minus sign if the number is negative. The precision // specifier indicates the minimum number of digits desired in the resulting string. If required, // the number is padded with zeros to its left to produce the number of digits given by the // precision specifier. int numDigitsPrinted = cchMax - ichDst; return new String(rgch, ichDst, cchMax - ichDst); } static void Main(string[] args) { var bits = new uint[] { 0x1245AC78,0xBFD71892,0xFF6299CE,0xA3D8D694, 0xA24ECB3E,0x4C406600,0x020AE477,0x54405309, 0x70BC4D39,0x906B69E8,0x0E2A6085,0x589CB3C2, 0x8562E032,0x63E99843,0xA6995436,0xDF9174EB, 0x74970141,0xE0E80D33,0x0797CE5D,0xE224CD9E, 0xD2398748,0xBE783C90,0x7DF3EEAA,0x7359E6DF, 0x09680382,0x26884949,0x7262131A,0xAB1F3DCB, 0xA24ECB3E,0x4C406600,0x020AE477,0x54405309}; Array.Reverse(bits); Console.WriteLine(FormatBigInteger(bits, null, null)); Console.ReadLine(); } }

Источник

Читайте также:  Can php run in html file
Оцените статью