< Summary

Information
Class: ValidateLib.TabularData.Datatypes.NumericDatatypes.NumericBaseDT
Assembly: validatelib.dll
File(s): C:\skola_karlovka\RP\code\csv-validator\CSV_Validator\ValidateLib\TabularData\Datatypes\NumericDatatypes\NumericBaseDT.cs
Line coverage
94%
Covered lines: 284
Uncovered lines: 17
Coverable lines: 301
Total lines: 582
Line coverage: 94.3%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

C:\skola_karlovka\RP\code\csv-validator\CSV_Validator\ValidateLib\TabularData\Datatypes\NumericDatatypes\NumericBaseDT.cs

#LineLine coverage
 1using ExtendedNumerics;
 2using System.Numerics;
 3using System.Text;
 4using System.Text.RegularExpressions;
 5using ValidateLib.ErrorsAndWarnings.Errors;
 6using ValidateLib.ErrorsAndWarnings.Warnings;
 7using ValidateLib.Metadata.Descriptors;
 8
 9namespace ValidateLib.TabularData.Datatypes.NumericDatatypes
 10{
 11
 12
 13    public abstract class NumericBaseDT : BaseDT, IValue
 14    {
 115        protected float Percent { get; set; } = 1;
 116        protected float Permile { get; set; } = 1;
 117        protected BigDecimal Exponent { get; set; } = 1;
 118        public BigDecimal Value { get; set; }
 19
 120        protected SpecialTypes SpecialType { get; set; } = SpecialTypes.Normal;
 21
 122        protected string? GroupChar { get; set; } = null;
 123        protected string DecimalChar { get; set; } = ".";
 24
 125        public List<Warning> Warnings { get; set; } = new List<Warning>();
 126        public NumericBaseDT() { }
 127        protected NumericBaseDT(string stringValue) : base(stringValue)
 28        {
 129            ProcessPercenPermileExponent();
 30
 131        }
 32
 133        protected NumericBaseDT(string strValue, FormatDescriptor format) : base(strValue, format)
 34        {
 135            if (format is null)
 036                ErrorFactory.ThrowInvalidFormatError("Format is null");
 37
 138            GroupChar = format!.groupChar;
 139            DecimalChar = format.decimalChar is null ? DecimalChar : format.decimalChar;
 40
 141            if (format.pattern is not null)
 42            {
 43
 144                ProcessValuePatternPresent(strValue, format);
 45
 46
 47            }
 48            else
 49            {
 150                if (HandleSpecialTypes(strValue))
 151                    return;
 52
 153                string pattern = $@"^[+-]?\d+(\{GroupChar}\d+)*(\{DecimalChar}\d+)?([Ee][+-]?\d+)?[%‰]?$";
 154                if (!Regex.IsMatch(strValue, pattern))
 155                    ErrorFactory.ThrowDatatypeValidationError(strValue);
 56
 157                ProcessPercenPermileExponent();
 58
 159                if (GroupChar is not null)
 160                    ProcessGroupChar();
 161                stringValue = stringValue.Replace(DecimalChar, ".");
 62                try
 63                {
 164                    Value = BigDecimal.Parse(stringValue);
 165                }
 066                catch (FormatException)
 67                {
 068                    ErrorFactory.ThrowDatatypeValidationError();
 069                }
 70
 71            }
 172        }
 73
 74        /// <summary>
 75        /// Here it is assumed that the format pattern has been checked for validity
 76        /// </summary>
 77        /// <param name="strValue"></param>
 78        /// <param name="format"></param>
 79        void ProcessValuePatternPresent(string strValue, FormatDescriptor format)
 80        {
 81            // set default values
 182            if (GroupChar is null)
 183                GroupChar = ",";
 184            if (DecimalChar is null)
 085                DecimalChar = ".";
 86
 187            string formatPattern = format.pattern!;
 188            stringValue = strValue.ToUpper();
 89
 190            string intPart = "";
 191            string? fractionPart = null;
 192            string? exponentPart = null;
 93
 194            string[] exponentParts = formatPattern.Split('E');
 195            if (exponentParts.Count() == 2)
 196                exponentPart = exponentParts[1];
 197            string[] fractionParts = exponentParts[0].Split(DecimalChar);
 198            if (fractionParts.Count() == 2)
 199                fractionPart = fractionParts[1];
 1100            intPart = fractionParts[0];
 101
 102
 1103            string regexPrefix = "";
 1104            string regexSuffix = "";
 105
 1106            ProcessPrefixAndSuffix(ref formatPattern, ref regexPrefix, ref regexSuffix);
 107
 1108            string regexIntPart = GetRegexForIntPart(intPart);
 1109            string regexFrationalPart = GetRegexForFractionalPart(fractionPart);
 1110            string regexExponentPart = GetRegexForExponentPart(exponentPart);
 111
 1112            string completeRegex = $"^({regexPrefix}{regexIntPart}{regexFrationalPart}{regexExponentPart}{regexSuffix})$
 113
 1114            if (!Regex.IsMatch(strValue, completeRegex))
 1115                ErrorFactory.ThrowDatatypeValidationError("Value not matching pattern");
 116
 1117            ProcessPercenPermileExponentPatternPresent();
 118
 1119            if (GroupChar is not null)
 1120                ProcessGroupChar();
 1121            if (DecimalChar is not null)
 1122                ProcessDecimalChar();
 123
 124            try
 125            {
 1126                Value = BigDecimal.Parse(stringValue);
 1127            }
 0128            catch (FormatException)
 129            {
 0130                ErrorFactory.ThrowDatatypeValidationError();
 0131            }
 132
 1133            ResolvePercentPermileExponent();
 134
 1135        }
 136
 137        string GetRegexForIntPart(string formatPatternIntPart)
 138        {
 1139            int primaryGroupingSizeIntPart = 0;
 1140            int secondaryGroupingSizeIntPart = 0;
 141
 1142            GetPrimaryAndSecondaryGroupingSizes(formatPatternIntPart, GroupChar!, out primaryGroupingSizeIntPart, out se
 1143            int minDigitsCount = GetMinDigitsCount(formatPatternIntPart);
 144
 145
 1146            string prefixRegex = GetRegexForPrefix(formatPatternIntPart);
 1147            if (formatPatternIntPart[0] == '-' || formatPatternIntPart[0] == '+') formatPatternIntPart.Substring(1);
 1148            string digitsRegex = GetRegexForDigitsIntPart(formatPatternIntPart, minDigitsCount, GroupChar!, primaryGroup
 1149            return prefixRegex + digitsRegex;
 150
 151        }
 152
 153        string GetRegexForFractionalPart(string? formatPatternFractionalPart)
 154        {
 1155            if (formatPatternFractionalPart is null) return "";
 1156            int primaryGroupingSizeFractionallPart = 0;
 1157            int secondaryGroupingSizeFractionalPart = 0;
 158
 1159            GetPrimaryAndSecondaryGroupingSizes(
 1160                formatPatternFractionalPart,
 1161                GroupChar!,
 1162                out primaryGroupingSizeFractionallPart,
 1163                out secondaryGroupingSizeFractionalPart,
 1164                true);
 165
 1166            int minDigitsCount = GetMinDigitsCount(formatPatternFractionalPart, reversed: true);
 167
 1168            string digitsRegex = GetRegexForDigitsFractionPart(formatPatternFractionalPart, minDigitsCount, GroupChar!, 
 169
 1170            if (minDigitsCount == 0) return $"({Regex.Escape(DecimalChar) + digitsRegex})?";
 1171            return Regex.Escape(DecimalChar) + digitsRegex;
 172
 173
 174        }
 175
 176        string GetRegexForExponentPart(string? formatPatternExponentPart)
 177        {
 1178            if (formatPatternExponentPart is null) return "";
 179
 1180            string prefix = GetRegexForPrefix(formatPatternExponentPart);
 1181            int minDigits = formatPatternExponentPart.Count(c => c == '0');
 1182            if (formatPatternExponentPart[0] == '-' || formatPatternExponentPart[0] == '+') formatPatternExponentPart.Su
 183
 1184            return "E" + prefix + $"\\d{{{minDigits},}}";
 185        }
 186
 187        string GetRegexForDigitsIntPart(string formatPattern, int minDigits, string groupChar, int primaryGroupingSize =
 188        {
 1189            if (primaryGroupingSize == 0) return $"\\d{{{minDigits},}}";
 1190            else if (secondaryGorupingSize == 0)
 191            {
 1192                int numberOfWholeGroups = minDigits / primaryGroupingSize;
 1193                int moduloWholeGroups = minDigits % primaryGroupingSize;
 194
 1195                var regexBuilder = new StringBuilder();
 196
 1197                if (numberOfWholeGroups > 1)
 198                {
 0199                    regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{primaryGroupingSize},{primaryGroupingSize}}}){
 200                }
 201
 1202                if (moduloWholeGroups == 0)
 203                {
 0204                    regexBuilder.Insert(0, $"\\d{{{primaryGroupingSize},{primaryGroupingSize}}}");
 0205                    regexBuilder.Insert(0, $"(\\d{{{primaryGroupingSize},{primaryGroupingSize}}}{Regex.Escape(groupChar)
 0206                    regexBuilder.Insert(0, $"(\\d{{{1},{primaryGroupingSize}}}{Regex.Escape(groupChar)})?");
 207                }
 208                else
 209                {
 1210                    regexBuilder.Insert(0, $"\\d{{{moduloWholeGroups},{moduloWholeGroups}}}");
 1211                    regexBuilder.Insert(0, $"((\\d{{{1},{primaryGroupingSize}}}{Regex.Escape(groupChar)})?" +
 1212                        $"(" +
 1213                        $"(\\d{{{primaryGroupingSize},{primaryGroupingSize}}}{Regex.Escape(groupChar)})*" +
 1214                        $"\\d{{{primaryGroupingSize - moduloWholeGroups},{primaryGroupingSize - moduloWholeGroups}}})|" 
 1215                        $"\\d{{{0},{primaryGroupingSize - moduloWholeGroups}}})");
 216                }
 217
 1218                return regexBuilder.ToString();
 219
 220            }
 221            else
 222            {
 223                string regex = "";
 1224                var regexBuilder = new StringBuilder();
 1225                if (primaryGroupingSize >= minDigits)
 226                {
 1227                    if (primaryGroupingSize == minDigits)
 228                    {
 1229                        regexBuilder.Append($"\\d{{{primaryGroupingSize},{primaryGroupingSize}}}");
 1230                        regexBuilder.Insert(0, $"(\\d{{{secondaryGorupingSize},{secondaryGorupingSize}}}{Regex.Escape(gr
 1231                        regexBuilder.Insert(0, $"(\\d{{{1},{secondaryGorupingSize}}}{Regex.Escape(groupChar)})?");
 232                    }
 233                    else
 234                    {
 1235                        regexBuilder.Append($"\\d{{{minDigits},{minDigits}}}");
 1236                        regexBuilder.Insert(0, $"((\\d{{{1},{secondaryGorupingSize}}}{Regex.Escape(groupChar)})?((\\d{{{
 237                    }
 238                }
 239                else
 240                {
 1241                    regex = $"\\d{{{primaryGroupingSize},{primaryGroupingSize}}}";
 1242                    regexBuilder.Append($"\\d{{{primaryGroupingSize},{primaryGroupingSize}}}");
 243
 244
 1245                    minDigits -= primaryGroupingSize;
 1246                    if (minDigits > 0)
 247                    {
 1248                        regexBuilder.Insert(0, $"{Regex.Escape(groupChar)}");
 249                    }
 250
 251
 1252                    int numberOfWholeGroups = minDigits / secondaryGorupingSize;
 1253                    int moduloWholeGorups = minDigits % secondaryGorupingSize;
 254
 1255                    if (numberOfWholeGroups > 1)
 256                    {
 0257                        regexBuilder.Insert(0, $"({Regex.Escape(groupChar)}\\d{{{secondaryGorupingSize},{secondaryGorupi
 258                    }
 1259                    if (moduloWholeGorups == 0)
 260                    {
 261
 1262                        regexBuilder.Insert(0, $"\\d{{{secondaryGorupingSize},{secondaryGorupingSize}}}");
 1263                        regexBuilder.Insert(0, $"(\\d{{{secondaryGorupingSize},{secondaryGorupingSize}}}{Regex.Escape(gr
 1264                        regexBuilder.Insert(0, $"(\\d{{{1},{secondaryGorupingSize}}}{Regex.Escape(groupChar)})?");
 265                    }
 266                    else
 267                    {
 1268                        regexBuilder.Insert(0, $"\\d{{{moduloWholeGorups},{moduloWholeGorups}}}");
 1269                        regexBuilder.Insert(0, $"((\\d{{{1},{secondaryGorupingSize}}}{Regex.Escape(groupChar)})?((\\d{{{
 270                    }
 271
 272
 273                }
 1274                return regexBuilder.ToString();
 275            }
 276        }
 277
 278        string GetRegexForDigitsFractionPart(string formatPattern, int minDigits, string groupChar, int primaryGroupingS
 279        {
 1280            if (minDigits == 0) minDigits = 1;
 281
 1282            var regexBuilder = new StringBuilder();
 1283            int maxDigitsCount = formatPattern.Count(c => c == '#' || c == '0');
 284
 1285            if (primaryGroupingSize == 0)
 286            {
 1287                regexBuilder.Append($"\\d{{{minDigits},{maxDigitsCount}}}");
 288            }
 1289            else if (secondaryGroupingSize == 0)
 290            {
 1291                int numberOfWholeGroups = minDigits / primaryGroupingSize;
 1292                int moduloWholeGroups = minDigits % primaryGroupingSize;
 293
 1294                if (numberOfWholeGroups > 0)
 295                {
 1296                    regexBuilder.Append($"\\d{{{primaryGroupingSize},{primaryGroupingSize}}}");
 1297                    if (numberOfWholeGroups > 1)
 1298                        regexBuilder.Append($"({Regex.Escape(groupChar)}){{{numberOfWholeGroups - 1},{numberOfWholeGroup
 299                }
 300
 1301                if (moduloWholeGroups == 0)
 302                {
 1303                    regexBuilder.Append($"(\\d{{{primaryGroupingSize},{primaryGroupingSize}}})*");
 1304                    regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{1},{primaryGroupingSize}}})?");
 305                }
 306                else
 307                {
 1308                    if (numberOfWholeGroups > 0)
 1309                        regexBuilder.Append($"{Regex.Escape(groupChar)}");
 1310                    regexBuilder.Append($"\\d{{{moduloWholeGroups},{moduloWholeGroups}}}");
 1311                    regexBuilder.Append("(");
 312
 1313                    regexBuilder.Append("(");
 1314                    regexBuilder.Append($"\\d{{{primaryGroupingSize - moduloWholeGroups},{primaryGroupingSize - moduloWh
 1315                    regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{primaryGroupingSize},{primaryGroupingSize}}})*
 1316                    regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{1},{primaryGroupingSize}}})?");
 1317                    regexBuilder.Append(")|");
 318
 1319                    regexBuilder.Append("(");
 1320                    regexBuilder.Append($"\\d{{{0},{primaryGroupingSize - moduloWholeGroups}}}");
 1321                    regexBuilder.Append(")");
 322
 1323                    regexBuilder.Append(")");
 324                }
 325            }
 326            else
 327            {
 1328                if (primaryGroupingSize >= minDigits)
 329                {
 1330                    if (primaryGroupingSize == minDigits)
 331                    {
 1332                        regexBuilder.Append($"\\d{{{primaryGroupingSize},{primaryGroupingSize}}}");
 1333                        regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{secondaryGroupingSize},{secondaryGroupingS
 1334                        regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{1},{secondaryGroupingSize}}})?");
 335                    }
 336                    else
 337                    {
 1338                        regexBuilder.Append($"\\d{{{minDigits},{minDigits}}}");
 1339                        regexBuilder.Append("(");
 1340                        regexBuilder.Append("(");
 1341                        regexBuilder.Append($"\\d{{{0},{primaryGroupingSize - minDigits}}}");
 1342                        regexBuilder.Append(")|");
 1343                        regexBuilder.Append($"\\d{{{primaryGroupingSize - minDigits},{primaryGroupingSize - minDigits}}}
 1344                        regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{secondaryGroupingSize},{secondaryGroupingS
 1345                        regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{1},{secondaryGroupingSize}}})?");
 1346                        regexBuilder.Append(")");
 347                    }
 348                }
 349                else
 350                {
 1351                    regexBuilder.Append($"\\d{{{primaryGroupingSize},{primaryGroupingSize}}}");
 1352                    minDigits -= primaryGroupingSize;
 1353                    if (minDigits > 0) regexBuilder.Append($"{Regex.Escape(groupChar)}");
 354
 1355                    int numberOfWholeGroups = minDigits / secondaryGroupingSize;
 1356                    int moduloWholeGroups = minDigits % secondaryGroupingSize;
 357
 1358                    if (numberOfWholeGroups > 1)
 359                    {
 0360                        regexBuilder.Append($"(\\d{{{secondaryGroupingSize},{secondaryGroupingSize}}}{Regex.Escape(group
 361                    }
 362
 1363                    if (moduloWholeGroups == 0)
 364                    {
 1365                        regexBuilder.Append($"\\d{{{secondaryGroupingSize},{secondaryGroupingSize}}}");
 1366                        regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{secondaryGroupingSize},{secondaryGroupingS
 1367                        regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{1},{secondaryGroupingSize}}})?");
 368                    }
 369                    else
 370                    {
 1371                        regexBuilder.Append($"\\d{{{moduloWholeGroups},{moduloWholeGroups}}}");
 1372                        regexBuilder.Append("(");
 1373                        regexBuilder.Append("(");
 1374                        regexBuilder.Append($"\\d{{{primaryGroupingSize - moduloWholeGroups},{secondaryGroupingSize - mo
 1375                        regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{secondaryGroupingSize},{secondaryGroupingS
 1376                        regexBuilder.Append(")|");
 1377                        regexBuilder.Append($"\\d{{{0},{secondaryGroupingSize - moduloWholeGroups}}}");
 1378                        regexBuilder.Append($"({Regex.Escape(groupChar)}\\d{{{1},{secondaryGroupingSize}}})?");
 1379                        regexBuilder.Append(")");
 380                    }
 381                }
 382            }
 383
 1384            return regexBuilder.ToString();
 385        }
 386
 387
 388        string GetRegexForPrefix(string pattern)
 389        {
 1390            string regex = @"[+-]?";
 1391            if (pattern[0] == '+') regex = @"[+]";
 1392            if (pattern[0] == '-') regex = @"[-]";
 393
 1394            return regex;
 395        }
 396
 397        int GetMinDigitsCount(string pattern, bool reversed = false)
 398        {
 1399            StringBuilder sb = new StringBuilder();
 1400            foreach (var c in pattern)
 401            {
 1402                if (c == '0' || c == '#') sb.Append(c);
 403            }
 1404            var clearedString = sb.ToString();
 405
 1406            if (reversed)
 407            {
 1408                char[] charArray = clearedString.ToCharArray();
 1409                Array.Reverse(charArray);
 1410                clearedString = new string(charArray);
 411            }
 412
 1413            if (clearedString.IndexOf('0') != -1)
 1414                return clearedString.Length - clearedString.IndexOf('0');
 1415            else return 0;
 416
 417        }
 418        static void GetPrimaryAndSecondaryGroupingSizes(string formatPattern, string groupChar, out int primaryGroupingS
 419        {
 1420            primaryGroupingSize = 0;
 1421            secondaryGroupingSize = 0;
 422
 1423            if (reversed)
 424            {
 1425                char[] charArray = formatPattern.ToCharArray();
 1426                Array.Reverse(charArray);
 1427                formatPattern = new string(charArray);
 428            }
 1429            string[] formatParts = formatPattern.Split(groupChar);
 1430            if (formatParts.Count() >= 2)
 1431                primaryGroupingSize = formatParts[formatParts.Count() - 1].Length;
 1432            if (formatParts.Count() >= 3)
 1433                secondaryGroupingSize = formatParts[formatParts.Count() - 2].Length;
 1434        }
 435
 1436        void ProcessGroupChar() => stringValue = stringValue.Replace(GroupChar!, "");
 437
 438        void ProcessDecimalChar()
 439        {
 1440            if (DecimalChar != ".")
 0441                stringValue = stringValue.Replace(DecimalChar, ".");
 1442        }
 443
 444        void ProcessPrefixAndSuffix(ref string formatPattern, ref string regexPrefix, ref string regexSuffix)
 445        {
 1446            if (formatPattern[0] == '%')
 447            {
 1448                regexPrefix = "%";
 1449                formatPattern = formatPattern.Substring(1);
 450            }
 451
 1452            if (formatPattern[0] == '‰')
 453            {
 1454                regexPrefix = "‰";
 1455                formatPattern = formatPattern.Substring(1);
 456            }
 1457            if (formatPattern[formatPattern.Length - 1] == '%')
 458            {
 1459                regexSuffix = "%";
 1460                formatPattern = formatPattern.Substring(0, formatPattern.Length - 1);
 461            }
 462
 1463            if (formatPattern[formatPattern.Length - 1] == '‰')
 464            {
 1465                regexSuffix = "‰";
 1466                formatPattern = formatPattern.Substring(0, formatPattern.Length - 1);
 467            }
 1468        }
 469
 470        public static bool IsFormatPatternValidAndSupported(FormatDescriptor formatDescriptor)
 471        {
 472            // verify the pattern only contains allowed characters
 1473            if (formatDescriptor.pattern is null) return true;
 1474            string decimalChar = formatDescriptor.decimalChar is null ? "." : formatDescriptor.decimalChar;
 1475            string groupChar = formatDescriptor.groupChar is null ? "," : formatDescriptor.groupChar;
 1476            char[] supportedChars = new char[] { '0', '#', '%', '‰', '-', '+', 'E' };
 477
 1478            string formatPattern = formatDescriptor.pattern;
 1479            string formatPatternWithoutDecAndGrChars = formatPattern.Replace(decimalChar, "").Replace(groupChar, "");
 1480            foreach (var c in formatPatternWithoutDecAndGrChars)
 481            {
 1482                if (!supportedChars.Contains(c)) return false;
 483            }
 484
 485            // verify the pattern is in correct format
 1486            string correctNumericPatternRegex =
 1487                $@"^(%|‰)?[+-]?[#0]+({Regex.Escape(groupChar)}[#0]+)*({Regex.Escape(decimalChar)}[#0]+({Regex.Escape(gro
 488            /*
 489            Regex regex = new Regex($@"((E[+]?[#0]+({Regex.Escape(groupChar)}[#0]+)*)?)?(%|‰)?");
 490            var match = regex.Match(formatPattern);
 491            */
 492
 1493            if (!Regex.IsMatch(formatPattern, correctNumericPatternRegex))
 1494                return false;
 1495            return true;
 496        }
 497
 498        void ProcessPercenPermileExponent()
 499        {
 1500            if (stringValue.EndsWith("%"))
 501            {
 1502                stringValue = stringValue.Replace("%", "");
 1503                Percent = 0.01F;
 504            }
 1505            else if (stringValue.EndsWith("‰"))
 506            {
 1507                stringValue = stringValue.Replace("‰", "");
 1508                Permile = 0.001F;
 509            }
 1510            else if (stringValue.Contains('E'))
 1511                ProcessExponent();
 512
 1513        }
 514
 515        void ProcessPercenPermileExponentPatternPresent()
 516        {
 1517            if (format!.pattern!.StartsWith("%") || format!.pattern!.EndsWith("%"))
 518            {
 1519                stringValue = stringValue.Replace("%", "");
 1520                Percent = 0.01F;
 521            }
 522
 1523            if (format!.pattern!.StartsWith("‰") || format!.pattern!.EndsWith("‰"))
 524            {
 1525                stringValue = stringValue.Replace("‰", "");
 1526                Permile = 0.001F;
 527            }
 1528            else if (format!.pattern!.Contains('E'))
 1529                ProcessExponent();
 530
 1531        }
 532
 533        void ProcessExponent()
 534        {
 535            try
 536            {
 1537                string[] stringParts = stringValue.Split("E");
 1538                if (stringParts.Length == 2)
 539                {
 1540                    var exponentPart = stringParts[1];
 1541                    var exponentPartInt = long.Parse(exponentPart);
 1542                    Exponent = BigDecimal.Pow(BigDecimal.Ten, new BigInteger(exponentPartInt));
 1543                    stringValue = stringParts[0];
 544                }
 545                else
 0546                    ErrorFactory.ThrowDatatypeValidationError(stringValue);
 1547            }
 1548            catch (Exception)
 549            {
 1550                ErrorFactory.ThrowDatatypeValidationError(stringValue);
 0551            }
 552
 1553        }
 554
 1555        protected void ResolvePercentPermileExponent() => Value = Value * Percent * Permile * Exponent;
 556
 557        bool HandleSpecialTypes(string strValue)
 558        {
 1559            if (strValue == "NaN")
 560            {
 1561                SpecialType = SpecialTypes.NaN;
 1562                return true;
 563            }
 1564            if (strValue == "-INF")
 565            {
 1566                SpecialType = SpecialTypes.NEGATIVE_INF;
 1567                return true;
 568            }
 1569            if (strValue == "INF")
 570            {
 1571                SpecialType = SpecialTypes.POSITIVE_INF;
 1572                return true;
 573            }
 1574            return false;
 575
 576
 577        }
 578
 1579        public override bool IsPatternValid(FormatDescriptor format) => IsFormatPatternValidAndSupported(format);
 580
 581    }
 582}