Diff
checker
Texte
Texte
Images
Documents
Excel
Dossiers
Legal
Enterprise
Application de bureau
Prix
Se connecter
Télécharger Diffchecker Desktop
Comparer le texte
Trouver la différence entre deux fichiers texte
Outils
Historique
Affichage
Vue
Divisé
Unifié
Éditeur live
Masquer les espaces
Cacher identiques
Sans retour à la ligne
Niveau de précision
Intelligent
Syntaxe
Aucun
Modifier l’apparence
Traitement
Ignorer
Transformer le texte
Aller au premier écart
Modifier l'entrée
Diffchecker Desktop
La façon la plus sécurisée d'utiliser Diffchecker. Obtenez l'application Diffchecker Desktop : vos diffs ne quittent jamais votre ordinateur !
Obtenir Desktop
TryParseNumber_char
Créé
il y a 3 ans
Le diff n'expire jamais
Effacer
Exporter
Partager
Expliquer
7 suppressions
Lignes
Total
Supprimé
Caractères
Total
Supprimé
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
258 lignes
Copier tout
13 ajouts
Lignes
Total
Ajouté
Caractères
Total
Ajouté
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
265 lignes
Copier tout
Copier
Copié
Copier
Copié
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érences enregistrées
Texte d'origine
Ouvrir un fichier
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; }
Texte modifié
Ouvrir un fichier
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; }
Trouver la différence