Ejemplo n.º 1
0
        /// <summary>
        /// Parse string value to <see cref="MbfFloat"/>
        /// </summary>
        /// <param name="value">String value to parse</param>
        /// <param name="allowNonNumbers">Allow non-number chars in string value</param>
        /// <returns><see cref="MbfDouble"/> if value if double else <see cref="MbfSingle"/></returns>
        public static MbfFloat Parse(string value, bool allowNonNumbers = true)
        {
            var foundSign       = false;
            var foundPoint      = false;
            var foundExpression = false;

            var foundExpSign       = false;
            var expressionNegitive = false;
            var negitive           = false;

            var exp10    = 0;
            var exponent = 0;
            var mantissa = 0UL;
            var digits   = 0;
            var zeros    = 0;

            var isDouble = false;
            var isSingle = false;

            foreach (var c in value)
            {
                // ignore whitespace throughout (x = 1   234  56  .5  means x=123456.5 in gw!)
                if (Constants.Whitepsace.Contains(c))
                {
                    continue;
                }

                // determine sign
                if (!foundSign)
                {
                    foundSign = true;
                    // number has started; if no sign encountered here, sign must be pos.
                    if (c == '+' || c == '-')
                    {
                        negitive = c == '-';
                        continue;
                    }
                }

                // parse numbers and decimal points, until 'E' or 'D' is found
                if (!foundExpression)
                {
                    if (Constants.DecimalDigits.Contains(c))
                    {
                        mantissa *= 10;
                        mantissa += (ulong)(c - '0');

                        if (foundPoint)
                        {
                            exp10 -= 1;
                        }

                        // keep track of precision digits
                        if (mantissa != 0)
                        {
                            digits += 1;
                            if (foundPoint && c == '0')
                            {
                                zeros += 1;
                            }
                            else
                            {
                                zeros = 0;
                            }
                        }

                        continue;
                    }

                    if (c == '.')
                    {
                        foundPoint = true;
                        continue;
                    }

                    if ("DE".Contains(char.ToUpper(c)))
                    {
                        foundExpression = true;
                        isDouble        = c == 'D' || c == 'd';
                        continue;
                    }

                    if (c == '!')
                    {
                        // makes it a single, even if more than eight digits specified
                        isSingle = true;
                        break;
                    }

                    if (c == '#')
                    {
                        isDouble = true;
                        break;
                    }

                    if (allowNonNumbers)
                    {
                        break;
                    }

                    return(null);
                }

                if (!foundExpSign)
                {
                    foundExpSign = true;
                    // exponent has started; if no sign given, it must be pos.
                    if (c == '-' || c == '+')
                    {
                        expressionNegitive = c == '-';
                        continue;
                    }
                }

                if (Constants.DecimalDigits.Contains(c))
                {
                    exponent *= 10;
                    exponent += c - '0';
                    continue;
                }

                if (allowNonNumbers)
                {
                    break;
                }

                return(null);
            }

            if (expressionNegitive)
            {
                exp10 -= exponent;
            }
            else
            {
                exp10 += exponent;
            }

            // eight or more digits means double, unless single override
            if (digits - zeros > 7 && !isSingle)
            {
                isDouble = true;
            }

            mantissa *= 0x100;
            var builder = new MbfFloatParser(isDouble)
            {
                IsNegitive = negitive,
                Exponent   = isDouble ? MbfDouble.Bias : MbfSingle.Bias,
                Mantissa   = mantissa
            };

            builder.Normalize();
            while (exp10 < 0)
            {
                builder.Divide10();
                exp10 += 1;
            }

            while (exp10 > 0)
            {
                builder.Multiply10();
                exp10 += 1;
            }

            builder.Normalize();
            return(builder.ToMbfFloat());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Convert MbfFloat to .NET string.
        /// </summary>
        /// <param name="screen">screen=True (ie PRINT) - leading space, no type sign</param>
        /// <param name="write"></param>
        /// <returns></returns>
        public string ToString(bool screen, bool write)
        {
            // zero exponent byte means zero
            if (IsZero)
            {
                string value;
                if (screen && !write)
                {
                    value = " 0";
                }
                else if (write)
                {
                    value = "0";
                }
                else
                {
                    value = "0" + TypeSign;
                }

                return(value);
            }

            var builder = new StringBuilder();

            // print sign
            if (IsNegitive)
            {
                builder.Append("-");
            }
            else if (screen && !write)
            {
                builder.Append(' ');
            }

            var mbf = new MbfFloatParser(this);
            int exponent10;

            var number = mbf.BringToRange(out exponent10);
            var digits = GetDigits(number, MbfDigitCount);

            // exponent for scientific notation
            exponent10 += mbf.MbfDigitCount - 1;
            if (exponent10 > mbf.MbfDigitCount - 1 || digits.Length - exponent10 > mbf.MbfDigitCount + 1)
            {
                // use scientific notation
                builder.Append(ScientificNotation(digits, exponent10, ExponentSign));
            }
            else
            {
                var typeSign = string.Empty;
                // use decimal notation
                if (!screen && !write)
                {
                    typeSign = TypeSign.ToString();
                }

                builder.Append(DecimalNotation(digits, exponent10, typeSign));
            }

            return(builder.ToString());
        }