Diff
checker
Testo
Testo
Immagini
Documenti
Excel
Cartelle
Legal
Enterprise
Applicazione per desktop
Prezzi
Accedi
Scarica Diffchecker Desktop
Confronta il testo
Trova la differenza tra due file di testo
Strumenti
Cronologia
Visualizzazione
Layout
Diviso
Unificato
Editor live
Nascondi spazi bianchi
Comprimi invariate
Senza a capo
Livello di dettaglio
Intelligente
Sintassi
Nessuno
Modifica aspetto
Elaborazione
Ignora
Trasforma testo
Vai alla prima modifica
Modifica input
Diffchecker Desktop
Il modo più sicuro per usare Diffchecker. Ottieni l'app Diffchecker Desktop: i tuoi diff non lasciano mai il tuo computer!
Ottieni Desktop
TryParseNumber_char
Creato
3 anni fa
Il diff non scade mai
Eliminare
Esporta
Condividere
Spiegare
7 rimozioni
Linee
Totale
Rimosso
Caratteri
Totale
Rimosso
Per continuare a utilizzare questa funzione, aggiorna a
Diff
checker
Pro
Visualizza prezzi
258 linee
Copia tutti
13 aggiunte
Linee
Totale
Aggiunto
Caratteri
Totale
Aggiunto
Per continuare a utilizzare questa funzione, aggiorna a
Diff
checker
Pro
Visualizza prezzi
265 linee
Copia tutti
Copia
Copiato
Copia
Copiato
private static unsafe bool TryParseNumber(scoped ref char* str, char* strEnd, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info)
private static unsafe bool TryParseNumber(scoped ref char* str, char* strEnd, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info)
{
{
Debug.Assert(str != null);
Debug.Assert(str != null);
Debug.Assert(strEnd != null);
Debug.Assert(strEnd != null);
Debug.Assert(str <= strEnd);
Debug.Assert(str <= strEnd);
Debug.Assert((styles & (NumberStyles.AllowHexSpecifier | NumberStyles.AllowBinarySpecifier)) == 0);
Debug.Assert((styles & (NumberStyles.AllowHexSpecifier | NumberStyles.AllowBinarySpecifier)) == 0);
const int StateSign = 0x0001;
const int StateSign = 0x0001;
const int StateParens = 0x0002;
const int StateParens = 0x0002;
const int StateDigits = 0x0004;
const int StateDigits = 0x0004;
const int StateNonZero = 0x0008;
const int StateNonZero = 0x0008;
const int StateDecimal = 0x0010;
const int StateDecimal = 0x0010;
const int StateCurrency = 0x0020;
const int StateCurrency = 0x0020;
Debug.Assert(number.DigitsCount == 0);
Debug.Assert(number.DigitsCount == 0);
Debug.Assert(number.Scale == 0);
Debug.Assert(number.Scale == 0);
Debug.Assert(!number.IsNegative);
Debug.Assert(!number.IsNegative);
Debug.Assert(!number.HasNonZeroTail);
Debug.Assert(!number.HasNonZeroTail);
number.CheckConsistency();
number.CheckConsistency();
string decSep; // decimal separator from NumberFormatInfo.
string decSep; // decimal separator from NumberFormatInfo.
string groupSep; // group separator from NumberFormatInfo.
string groupSep; // group separator from NumberFormatInfo.
string? currSymbol = null; // currency symbol from NumberFormatInfo.
string? currSymbol = null; // currency symbol from NumberFormatInfo.
bool parsingCurrency = false;
bool parsingCurrency = false;
if ((styles & NumberStyles.AllowCurrencySymbol) != 0)
if ((styles & NumberStyles.AllowCurrencySymbol) != 0)
{
{
currSymbol = info.CurrencySymbol;
currSymbol = info.CurrencySymbol;
// The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast.
// The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast.
// The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part).
// The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part).
decSep = info.CurrencyDecimalSeparator;
decSep = info.CurrencyDecimalSeparator;
groupSep = info.CurrencyGroupSeparator;
groupSep = info.CurrencyGroupSeparator;
parsingCurrency = true;
parsingCurrency = true;
}
}
else
else
{
{
decSep = info.NumberDecimalSeparator;
decSep = info.NumberDecimalSeparator;
groupSep = info.NumberGroupSeparator;
groupSep = info.NumberGroupSeparator;
}
}
int state = 0;
int state = 0;
char* p = str;
char* p = str;
char ch = p < strEnd ? *p : '\0';
char ch = p < strEnd ? *p : '\0';
char* next;
char* next;
while (true)
while (true)
{
{
// Eat whitespace unless we've found a sign which isn't followed by a currency symbol.
// Eat whitespace unless we've found a sign which isn't followed by a currency symbol.
// "-Kr 1231.47" is legal but "- 1231.47" is not.
// "-Kr 1231.47" is legal but "- 1231.47" is not.
if (!IsWhite(ch) || (styles & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && info.NumberNegativePattern != 2)))
if (!IsWhite(ch) || (styles & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && info.NumberNegativePattern != 2)))
{
{
if ((((styles & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || ((next = MatchNegativeSignChars(p, strEnd, info)) != null && (number.IsNegative = true))))
if ((((styles & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || ((next = MatchNegativeSignChars(p, strEnd, info)) != null && (number.IsNegative = true))))
{
{
state |= StateSign;
state |= StateSign;
p = next - 1;
p = next - 1;
}
}
else if (ch == '(' && ((styles & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0))
else if (ch == '(' && ((styles & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0))
{
{
state |= StateSign | StateParens;
state |= StateSign | StateParens;
number.IsNegative = true;
number.IsNegative = true;
}
}
else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null)
else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null)
{
{
state |= StateCurrency;
state |= StateCurrency;
currSymbol = null;
currSymbol = null;
// We already found the currency symbol. There should not be more currency symbols. Set
// We already found the currency symbol. There should not be more currency symbols. Set
// currSymbol to NULL so that we won't search it again in the later code path.
// currSymbol to NULL so that we won't search it again in the later code path.
p = next - 1;
p = next - 1;
}
}
else
else
{
{
break;
break;
}
}
}
}
ch = ++p < strEnd ? *p : '\0';
ch = ++p < strEnd ? *p : '\0';
}
}
int digCount = 0;
int digCount = 0;
int digEnd = 0;
int digEnd = 0;
int maxDigCount = number.Digits.Length - 1;
int maxDigCount = number.Digits.Length - 1;
int numberOfTrailingZeros = 0;
int numberOfTrailingZeros = 0;
while (true)
while (true)
{
{
if (IsDigit(ch))
if (IsDigit(ch))
{
{
state |= StateDigits;
state |= StateDigits;
if (ch != '0' || (state & StateNonZero) != 0)
if (ch != '0' || (state & StateNonZero) != 0)
{
{
if (digCount < maxDigCount)
if (digCount < maxDigCount)
{
{
number.Digits[digCount] = (byte)(ch);
number.Digits[digCount] = (byte)(ch);
if ((ch != '0') || (number.Kind != NumberBufferKind.Integer))
if ((ch != '0') || (number.Kind != NumberBufferKind.Integer))
{
{
digEnd = digCount + 1;
digEnd = digCount + 1;
}
}
}
}
Diff salvati
Testo originale
Apri file
private static unsafe bool TryParseNumber(scoped ref char* str, char* strEnd, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info) { Debug.Assert(str != null); Debug.Assert(strEnd != null); Debug.Assert(str <= strEnd); Debug.Assert((styles & (NumberStyles.AllowHexSpecifier | NumberStyles.AllowBinarySpecifier)) == 0); const int StateSign = 0x0001; const int StateParens = 0x0002; const int StateDigits = 0x0004; const int StateNonZero = 0x0008; const int StateDecimal = 0x0010; const int StateCurrency = 0x0020; Debug.Assert(number.DigitsCount == 0); Debug.Assert(number.Scale == 0); Debug.Assert(!number.IsNegative); Debug.Assert(!number.HasNonZeroTail); number.CheckConsistency(); string decSep; // decimal separator from NumberFormatInfo. string groupSep; // group separator from NumberFormatInfo. string? currSymbol = null; // currency symbol from NumberFormatInfo. bool parsingCurrency = false; if ((styles & NumberStyles.AllowCurrencySymbol) != 0) { currSymbol = info.CurrencySymbol; // The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast. // The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part). decSep = info.CurrencyDecimalSeparator; groupSep = info.CurrencyGroupSeparator; parsingCurrency = true; } else { decSep = info.NumberDecimalSeparator; groupSep = info.NumberGroupSeparator; } int state = 0; char* p = str; char ch = p < strEnd ? *p : '\0'; char* next; while (true) { // Eat whitespace unless we've found a sign which isn't followed by a currency symbol. // "-Kr 1231.47" is legal but "- 1231.47" is not. if (!IsWhite(ch) || (styles & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && info.NumberNegativePattern != 2))) { if ((((styles & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || ((next = MatchNegativeSignChars(p, strEnd, info)) != null && (number.IsNegative = true)))) { state |= StateSign; p = next - 1; } else if (ch == '(' && ((styles & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0)) { state |= StateSign | StateParens; number.IsNegative = true; } else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) { state |= StateCurrency; currSymbol = null; // We already found the currency symbol. There should not be more currency symbols. Set // currSymbol to NULL so that we won't search it again in the later code path. p = next - 1; } else { break; } } ch = ++p < strEnd ? *p : '\0'; } int digCount = 0; int digEnd = 0; int maxDigCount = number.Digits.Length - 1; int numberOfTrailingZeros = 0; while (true) { if (IsDigit(ch)) { state |= StateDigits; if (ch != '0' || (state & StateNonZero) != 0) { if (digCount < maxDigCount) { number.Digits[digCount] = (byte)(ch); if ((ch != '0') || (number.Kind != NumberBufferKind.Integer)) { digEnd = digCount + 1; } } else if (ch != '0') { // For decimal and binary floating-point numbers, we only // need to store digits up to maxDigCount. However, we still // need to keep track of whether any additional digits past // maxDigCount were non-zero, as that can impact rounding // for an input that falls evenly between two representable // results. number.HasNonZeroTail = true; } if ((state & StateDecimal) == 0) { number.Scale++; } if (digCount < maxDigCount) { // Handle a case like "53.0". We need to ignore trailing zeros in the fractional part for floating point numbers, so we keep a count of the number of trailing zeros and update digCount later if (ch == '0') { numberOfTrailingZeros++; } else { numberOfTrailingZeros = 0; } } digCount++; state |= StateNonZero; } else if ((state & StateDecimal) != 0) { number.Scale--; } } else if (((styles & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, decSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberDecimalSeparator)) != null)) { state |= StateDecimal; p = next - 1; } else if (((styles & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, groupSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberGroupSeparator)) != null)) { p = next - 1; } else { break; } ch = ++p < strEnd ? *p : '\0'; } bool negExp = false; number.DigitsCount = digEnd; number.Digits[digEnd] = (byte)('\0'); if ((state & StateDigits) != 0) { if ((ch == 'E' || ch == 'e') && ((styles & NumberStyles.AllowExponent) != 0)) { char* temp = p; ch = ++p < strEnd ? *p : '\0'; if ((next = MatchChars(p, strEnd, info._positiveSign)) != null) { ch = (p = next) < strEnd ? *p : '\0'; } else if ((next = MatchNegativeSignChars(p, strEnd, info)) != null) { ch = (p = next) < strEnd ? *p : '\0'; negExp = true; } if (IsDigit(ch)) { int exp = 0; do { exp = exp * 10 + (ch - '0'); ch = ++p < strEnd ? *p : '\0'; if (exp > 1000) { exp = 9999; while (IsDigit(ch)) { ch = ++p < strEnd ? *p : '\0'; } } } while (IsDigit(ch)); if (negExp) { exp = -exp; } number.Scale += exp; } else { p = temp; ch = p < strEnd ? *p : '\0'; } } if (number.Kind == NumberBufferKind.FloatingPoint && !number.HasNonZeroTail) { // Adjust the number buffer for trailing zeros int numberOfFractionalDigits = digEnd - number.Scale; if (numberOfFractionalDigits > 0) { numberOfTrailingZeros = Math.Min(numberOfTrailingZeros, numberOfFractionalDigits); Debug.Assert(numberOfTrailingZeros >= 0); number.DigitsCount = digEnd - numberOfTrailingZeros; number.Digits[number.DigitsCount] = (byte)('\0'); } } while (true) { if (!IsWhite(ch) || (styles & NumberStyles.AllowTrailingWhite) == 0) { if ((styles & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || (((next = MatchNegativeSignChars(p, strEnd, info)) != null) && (number.IsNegative = true)))) { state |= StateSign; p = next - 1; } else if (ch == ')' && ((state & StateParens) != 0)) { state &= ~StateParens; } else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) { currSymbol = null; p = next - 1; } else { break; } } ch = ++p < strEnd ? *p : '\0'; } if ((state & StateParens) == 0) { if ((state & StateNonZero) == 0) { if (number.Kind != NumberBufferKind.Decimal) { number.Scale = 0; } if ((number.Kind == NumberBufferKind.Integer) && (state & StateDecimal) == 0) { number.IsNegative = false; } } str = p; return true; } } str = p; return false; }
Testo modificato
Apri file
private static unsafe bool TryParseNumber(scoped ref char* str, char* strEnd, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info) { Debug.Assert(str != null); Debug.Assert(strEnd != null); Debug.Assert(str <= strEnd); Debug.Assert((styles & (NumberStyles.AllowHexSpecifier | NumberStyles.AllowBinarySpecifier)) == 0); const int StateSign = 0x0001; const int StateParens = 0x0002; const int StateDigits = 0x0004; const int StateNonZero = 0x0008; const int StateDecimal = 0x0010; const int StateCurrency = 0x0020; Debug.Assert(number.DigitsCount == 0); Debug.Assert(number.Scale == 0); Debug.Assert(!number.IsNegative); Debug.Assert(!number.HasNonZeroTail); number.CheckConsistency(); string decSep; // decimal separator from NumberFormatInfo. string groupSep; // group separator from NumberFormatInfo. string? currSymbol = null; // currency symbol from NumberFormatInfo. bool parsingCurrency = false; if ((styles & NumberStyles.AllowCurrencySymbol) != 0) { currSymbol = info.CurrencySymbol; // The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast. // The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part). decSep = info.CurrencyDecimalSeparator; groupSep = info.CurrencyGroupSeparator; parsingCurrency = true; } else { decSep = info.NumberDecimalSeparator; groupSep = info.NumberGroupSeparator; } int state = 0; char* p = str; char ch = p < strEnd ? *p : '\0'; char* next; while (true) { // Eat whitespace unless we've found a sign which isn't followed by a currency symbol. // "-Kr 1231.47" is legal but "- 1231.47" is not. if (!IsWhite(ch) || (styles & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && info.NumberNegativePattern != 2))) { if ((((styles & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || ((next = MatchNegativeSignChars(p, strEnd, info)) != null && (number.IsNegative = true)))) { state |= StateSign; p = next - 1; } else if (ch == '(' && ((styles & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0)) { state |= StateSign | StateParens; number.IsNegative = true; } else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) { state |= StateCurrency; currSymbol = null; // We already found the currency symbol. There should not be more currency symbols. Set // currSymbol to NULL so that we won't search it again in the later code path. p = next - 1; } else { break; } } ch = ++p < strEnd ? *p : '\0'; } int digCount = 0; int digEnd = 0; int maxDigCount = number.Digits.Length - 1; int numberOfTrailingZeros = 0; while (true) { if (IsDigit(ch)) { state |= StateDigits; if (ch != '0' || (state & StateNonZero) != 0) { if (digCount < maxDigCount) { number.Digits[digCount] = (byte)(ch); if ((ch != '0') || (number.Kind != NumberBufferKind.Integer)) { digEnd = digCount + 1; } } else if (ch != '0') { // For decimal and binary floating-point numbers, we only // need to store digits up to maxDigCount. However, we still // need to keep track of whether any additional digits past // maxDigCount were non-zero, as that can impact rounding // for an input that falls evenly between two representable // results. number.HasNonZeroTail = true; } if ((state & StateDecimal) == 0) { number.Scale++; } if (digCount < maxDigCount) { // Handle a case like "53.0". We need to ignore trailing zeros in the fractional part for floating point numbers, so we keep a count of the number of trailing zeros and update digCount later if (ch == '0') { numberOfTrailingZeros++; } else { numberOfTrailingZeros = 0; } } digCount++; state |= StateNonZero; } else if ((state & StateDecimal) != 0) { number.Scale--; } } else if (((styles & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, decSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberDecimalSeparator)) != null)) { state |= StateDecimal; p = next - 1; } else if (((styles & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, groupSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberGroupSeparator)) != null)) { p = next - 1; } else { break; } ch = ++p < strEnd ? *p : '\0'; } bool negExp = false; number.DigitsCount = digEnd; number.Digits[digEnd] = (byte)('\0'); if ((state & StateDigits) != 0) { if ((ch == 'E' || ch == 'e') && ((styles & NumberStyles.AllowExponent) != 0)) { char* temp = p; ch = ++p < strEnd ? *p : '\0'; if ((next = MatchChars(p, strEnd, info.PositiveSign)) != null) { ch = (p = next) < strEnd ? *p : '\0'; } else if ((next = MatchNegativeSignChars(p, strEnd, info)) != null) { ch = (p = next) < strEnd ? *p : '\0'; negExp = true; } if (IsDigit(ch)) { int exp = 0; do { // Check if we are about to overflow past our limit of 9 digits if (exp >= 100_000_000) { // Set exp to Int.MaxValue to signify the requested exponent is too large. This will lead to an OverflowException later. exp = int.MaxValue; number.Scale = 0; // Finish parsing the number, a FormatException could still occur later on. while (char.IsAsciiDigit(ch)) { ch = ++p < strEnd ? *p : '\0'; } break; } exp = exp * 10 + (ch - '0'); ch = ++p < strEnd ? *p : '\0'; } while (IsDigit(ch)); if (negExp) { exp = -exp; } number.Scale += exp; } else { p = temp; ch = p < strEnd ? *p : '\0'; } } if (number.Kind == NumberBufferKind.FloatingPoint && !number.HasNonZeroTail) { // Adjust the number buffer for trailing zeros int numberOfFractionalDigits = digEnd - number.Scale; if (numberOfFractionalDigits > 0) { numberOfTrailingZeros = Math.Min(numberOfTrailingZeros, numberOfFractionalDigits); Debug.Assert(numberOfTrailingZeros >= 0); number.DigitsCount = digEnd - numberOfTrailingZeros; number.Digits[number.DigitsCount] = (byte)('\0'); } } while (true) { if (!IsWhite(ch) || (styles & NumberStyles.AllowTrailingWhite) == 0) { if ((styles & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || (((next = MatchNegativeSignChars(p, strEnd, info)) != null) && (number.IsNegative = true)))) { state |= StateSign; p = next - 1; } else if (ch == ')' && ((state & StateParens) != 0)) { state &= ~StateParens; } else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) { currSymbol = null; p = next - 1; } else { break; } } ch = ++p < strEnd ? *p : '\0'; } if ((state & StateParens) == 0) { if ((state & StateNonZero) == 0) { if (number.Kind != NumberBufferKind.Decimal) { number.Scale = 0; } if ((number.Kind == NumberBufferKind.Integer) && (state & StateDecimal) == 0) { number.IsNegative = false; } } str = p; return true; } } str = p; return false; }
Trovare la differenza