Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches

◆ NumberToBigInteger()

static bool System.Numerics.BigNumber.NumberToBigInteger ( ref BigNumberBuffer number,
out BigInteger result )
inlinestaticprivate

Definition at line 188 of file BigNumber.cs.

189 {
190 Span<uint> span = stackalloc uint[64];
191 Span<uint> currentBuffer2 = span;
192 int currentBufferSize = 0;
193 int[] arrayFromPool = null;
194 uint partialValue = 0u;
195 int partialDigitCount = 0;
196 int totalDigitCount = 0;
197 int numberScale = number.scale;
198 try
199 {
200 StringBuilder.ChunkEnumerator enumerator = number.digits.GetChunks().GetEnumerator();
201 while (enumerator.MoveNext())
202 {
203 if (!ProcessChunk(enumerator.Current.Span, ref currentBuffer2))
204 {
205 result = default(BigInteger);
206 return false;
207 }
208 }
209 if (partialDigitCount > 0)
210 {
211 MultiplyAdd(ref currentBuffer2, s_uint32PowersOfTen[partialDigitCount], partialValue);
212 }
213 int num;
214 for (num = numberScale - totalDigitCount; num >= 9; num -= 9)
215 {
216 MultiplyAdd(ref currentBuffer2, 1000000000u, 0u);
217 }
218 if (num > 0)
219 {
220 MultiplyAdd(ref currentBuffer2, s_uint32PowersOfTen[num], 0u);
221 }
222 int n;
223 uint[] rgu;
224 if (currentBufferSize == 0)
225 {
226 n = 0;
227 rgu = null;
228 }
229 else if (currentBufferSize == 1 && currentBuffer2[0] <= int.MaxValue)
230 {
231 n = (int)(number.sign ? (0L - (long)currentBuffer2[0]) : currentBuffer2[0]);
232 rgu = null;
233 }
234 else
235 {
236 n = ((!number.sign) ? 1 : (-1));
237 rgu = currentBuffer2.Slice(0, currentBufferSize).ToArray();
238 }
239 result = new BigInteger(n, rgu);
240 return true;
241 }
242 finally
243 {
244 if (arrayFromPool != null)
245 {
246 ArrayPool<int>.Shared.Return(arrayFromPool);
247 }
248 }
249 void MultiplyAdd(ref Span<uint> currentBuffer, uint multiplier, uint addValue)
250 {
251 Span<uint> span2 = currentBuffer.Slice(0, currentBufferSize);
252 uint num2 = addValue;
253 for (int i = 0; i < span2.Length; i++)
254 {
255 ulong num3 = (ulong)((long)multiplier * (long)span2[i] + num2);
256 span2[i] = (uint)num3;
257 num2 = (uint)(num3 >> 32);
258 }
259 if (num2 != 0)
260 {
261 if (currentBufferSize == currentBuffer.Length)
262 {
263 int[] array = arrayFromPool;
264 arrayFromPool = ArrayPool<int>.Shared.Rent(checked(currentBufferSize * 2));
265 Span<uint> span3 = MemoryMarshal.Cast<int, uint>(arrayFromPool);
266 currentBuffer.CopyTo(span3);
267 currentBuffer = span3;
268 if (array != null)
269 {
271 }
272 }
273 currentBuffer[currentBufferSize] = num2;
274 currentBufferSize++;
275 }
276 }
277 bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> currentBuffer)
278 {
279 int val = Math.Max(numberScale - totalDigitCount, 0);
280 ReadOnlySpan<char> readOnlySpan = chunkDigits.Slice(0, Math.Min(val, chunkDigits.Length));
281 bool flag = false;
282 uint num4 = partialValue;
283 int num5 = partialDigitCount;
284 int num6 = totalDigitCount;
285 for (int j = 0; j < readOnlySpan.Length; j++)
286 {
287 char c = chunkDigits[j];
288 if (c == '\0')
289 {
290 flag = true;
291 break;
292 }
293 num4 = num4 * 10 + (uint)(c - 48);
294 num5++;
295 num6++;
296 if (num5 == 9)
297 {
298 MultiplyAdd(ref currentBuffer, 1000000000u, num4);
299 num4 = 0u;
300 num5 = 0;
301 }
302 }
303 if (!flag)
304 {
305 ReadOnlySpan<char> readOnlySpan2 = chunkDigits.Slice(readOnlySpan.Length);
306 for (int k = 0; k < readOnlySpan2.Length; k++)
307 {
308 switch (readOnlySpan2[k])
309 {
310 default:
311 return false;
312 case '0':
313 continue;
314 case '\0':
315 break;
316 }
317 break;
318 }
319 }
320 partialValue = num4;
321 partialDigitCount = num5;
322 totalDigitCount = num6;
323 return true;
324 }
325 }
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
static readonly uint[] s_uint32PowersOfTen
Definition BigNumber.cs:29
unsafe ReadOnlySpan< T > Span

References System.array, System.Text.StringBuilder.ChunkEnumerator.Current, System.Text.StringBuilder.ChunkEnumerator.GetEnumerator(), System.L, System.ReadOnlySpan< T >.Length, System.Span< T >.Length, System.Math.Max(), System.Math.Min(), System.Text.StringBuilder.ChunkEnumerator.MoveNext(), System.Numerics.BigNumber.s_uint32PowersOfTen, System.Buffers.ArrayPool< T >.Shared, System.ReadOnlySpan< T >.Slice(), System.Span< T >.Slice(), and System.ReadOnlyMemory< T >.Span.

Referenced by System.Numerics.BigNumber.TryParseBigInteger().