跳至内容

C# 编程/ .NET 框架/控制台编程

来自维基教科书,开放世界中的开放书籍

控制台编程

[编辑 | 编辑源代码]

可以使用与使用相同 System.Console 类的 Read()ReadLine 方法类似的方法来收集输入

using System;
public class ExampleClass
{
    public static void Main()
    {
        Console.WriteLine("Greetings!  What is your name?");
        Console.Write("My name is: ");
        string name = Console.ReadLine();

        Console.WriteLine("Nice to meet you, " + name);
        Console.ReadKey();
    }
}

上面的程序请求用户的姓名并将其显示回来。最后的 Console.ReadKey() 在退出程序之前等待用户输入一个键。

以下示例程序展示了两种输出文本的方法

using System;

public class HelloWorld
{
    public static void Main()
    {
        Console.WriteLine("Hello World!");             // relies on "using System;"
        Console.Write("This is...");
        Console.Write(" my first program!\n");
        System.Console.WriteLine("Goodbye World!");    // no "using" statement required
    }
}

上面的代码显示以下文本

Hello World!
This is... my first program!
Goodbye World!

该文本是使用 System.Console 类输出的。顶部的 using 语句允许编译器找到 Console 类,而无需在每次使用时指定 System 命名空间。

中间行使用 Write() 方法,该方法不会自动创建新行。要指定新行,我们可以使用反斜杠-n (\n) 序列。如果出于任何原因我们想真正显示 \n 字符,我们添加第二个反斜杠 (\\n)。反斜杠在 C# 中被称为转义字符,因为它不被视为普通字符,而是允许我们对某些特殊字符(如换行符)进行编码。

Error 输出用于将错误特定消息转移到控制台。对于新手用户来说,这可能看起来很无意义,因为它与 输出(如上所述)的效果相同。如果您决定编写运行另一个应用程序(例如调度程序)的应用程序,您可能希望监控该程序的输出 - 更具体地说,您可能只想在发生错误时收到通知。如果您将程序编码为在发生错误时写入 Console.Error 流,您可以告诉您的调度程序监控此流,并反馈发送给它的任何信息。您的程序可能希望将这些错误消息记录到文件中,而不是在控制台中出现。

您可能希望在学习流和了解 Process 类之后重新学习此内容。

命令行参数

[编辑 | 编辑源代码]

命令行参数是在执行控制台程序之前传递给它的值。例如,Windows 命令提示符包含一个 copy 命令,该命令接受两个命令行参数。第一个参数是原始文件,第二个参数是新副本的位置或名称。自定义控制台应用程序也可以拥有参数。C# 是一种面向对象的编程语言。 .NET 框架是一种 Microsoft 编程语言,用于创建 Web 应用程序、控制台应用程序和移动应用程序。

using Sys
{
    public static void Main(string[] args)
    Console.WriteLine("Last Name: " + args[1]);
    Console.Read();
}

如果上面的代码编译成一个名为 username.exe 的程序,则可以使用两个参数(例如,“Bill”和“Gates”)从命令行执行它

C:\>username.exe Bill Gates

注意上面的 Main() 方法如何具有一个字符串数组参数。该程序假设将有两个参数。该假设使程序不安全。如果在没有预期数量的命令行参数的情况下运行它,它将在尝试访问丢失的参数时崩溃。为了使程序更加健壮,我们可以检查用户是否输入了所有必需的参数。

using System;

public class Test
{
    public static void Main(string[] args)
    {
        if(args.Length >= 1)
        Console.WriteLine(args[0]);
        if(args.Length >= 2)
        Console.WriteLine(args[1]);
    }
}

尝试运行程序,只输入您的名字或完全不输入名字。 args.Length 属性返回参数的总数。如果没有给出参数,它将返回零。

您还可以使用引号 ("") 将单个参数组合在一起。如果您期望许多参数,但需要包含空格(例如文件位置、文件名、全名等),这特别有用。

using System;

class Test
{
   public static void Main(string[] args)
   {
      for (int index = 0; index < args.Length; index++)
      {
         Console.WriteLine((index + 1) + ": " + args[index]);
      }
   }
}
C:\> Test.exe Separate words "grouped together"
1: Separate
2: words
3: grouped together

格式化输出

[编辑 | 编辑源代码]

Console.Write()Console.WriteLine() 允许您输出文本字符串,但也允许使用变量替换编写字符串。

这两个函数通常将字符串作为第一个参数。当添加其他对象时,无论是作为参数还是作为数组,该函数将扫描字符串以替换对象以代替标记。

例如

{
  int i = 10;
  Console.WriteLine("i = {0}", i);
}

{0} 由大括号标识,并引用需要替换的参数索引。您还可以在大括号中找到一个格式说明符,它以冒号开头,后面是问题中的说明符(例如 {0:G})。

舍入数字示例

[编辑 | 编辑源代码]

这是一个将数字舍入为字符串的小例子。它是 C# 的 Math 类的扩展。Round 方法的结果必须舍入为字符串,因为有效数字可能包含尾随零,如果使用数字格式,这些零将消失。以下是代码及其调用。欢迎您编写一个更短的版本以获得相同的结果,或者更正错误!

常量类包含重复的常量,这些常量在代码中应该只存在一次,以避免无意中的更改。(如果一个常量被无意中更改,很可能被发现,因为它在多个位置被使用。)

using System;

namespace ConsoleApplicationCommons
{
    class Common
    {
        /// <summary>Constant of comma or decimal point in German</summary>
        public const char COMMA = ',';
        /// <summary>Dash or minus constant</summary>
        public const char DASH = '-';
        /// <summary>
        /// The exponent sign in a scientific number, or the capital letter E
        /// </summary>
        public const char EXPONENT = 'E';
        /// <summary>The full stop or period</summary>
        public const char PERIOD = '.';
        /// <summary>The zero string constant used at several places</summary>
        public const String ZERO = "0";
    } // class Common
}

Math 类是对 <math.h> 库的增强,包含舍入计算。

using System;
using System.Globalization;
using System.IO;
using System.Text;

namespace ConsoleApplicationCommons
{
    /// <summary>
    /// Class for special mathematical calculations.
    /// ATTENTION: Should not depend on any other class except Java libraries!
    /// </summary>
    public class Maths
    {
        public static CultureInfo invC = CultureInfo.InvariantCulture;
        /// <summary>
        /// Value after which the language switches from scientific to double
        /// </summary>
        private const double E_TO_DOUBLE = 1E-4;
        /// <summary>
        /// Maximal digits after which Convert.ToString(…) becomes inaccurate.
        /// </summary>
        private const short MAX_CHARACTERS = 16;
        /// <summary>The string of zeros</summary>
        private static String strZeros = "000000000000000000000000000000000";

        /// <summary>
        /// Determines language-independently whether or not the character
        /// can be a decimal separator or not
        /// </summary>
        /// <param name="character">Character to be checked</param>
        /// <returns>
        /// true, if it can be a decimal separator in a language, and false
        /// otherwise.
        /// </returns>
        private static bool IsDecimalSeparator(char c)
        {
            return ((c == Common.COMMA) || (c == Common.PERIOD));
        }

        /// <summary>
        /// Determines how many zeros are to be appended after the decimal
        /// digits.
        /// </summary>
        /// <param name="separator">
        /// Language-specific decimal separator
        /// </param>
        /// <param name="d">Rounded number</param>
        /// <param name="significantsAfter">
        /// Significant digits after decimal
        /// </param>
        /// <returns>Requested value</returns>
        private static short CalculateMissingSignificantZeros(char separator,
            double d,
            short significantsAfter)
        {
            short after = FindSignificantsAfterDecimal(separator, d);

            short zeros = (short)(significantsAfter
                - ((after == 0) ? 1 : after));

            return (short)((zeros >= 0) ? zeros : 0);
        }

        /// <summary>
        /// Finds the decimal position language-independently.
        /// </summary>
        /// <param name="value">
        /// Value to be searched for the decimal separator
        /// </param>
        /// <returns>The position of the decimal separator</returns>
        private static short FindDecimalSeparatorPosition(String value)
        {
            short separatorAt = (short)value.IndexOf(Common.COMMA);

            return (separatorAt > -1)
                ? separatorAt : (short)value.IndexOf(Common.PERIOD);
        }

        /// <summary>
        /// Calculates the number of significant digits (without the sign and
        /// the decimal separator).
        /// </summary>
        /// <param name="separator">
        /// Language-specific decimal separator
        /// </param>
        /// <param name="d">Value where the digits are to be counted</param>
        /// <param name="significantsAfter">
        /// Number of decimal places after the separator
        /// </param>
        /// <returns>Number of significant digits</returns>
        private static short FindSignificantDigits(char separator,
            double d,
            short significantsAfter)
        {
            if (d == 0) return 0;
            else
            {
                String mantissa = FindMantissa(separator, 
                    Convert.ToString(d, invC));

                if (d == (long)d)
                {
                    mantissa = mantissa.Substring(0, mantissa.Length - 1);
                }

                mantissa = RetrieveDigits(mantissa);
                // Find the position of the first non-zero digit:
                short nonZeroAt = 0;

                for (; (nonZeroAt < mantissa.Length)
                        && (mantissa[nonZeroAt] == '0'); nonZeroAt++) ;

                return (short)mantissa.Substring(nonZeroAt).Length;
            }
        }

        /// <summary>
        /// Finds the significant digits after the decimal separator of a
        /// mantissa.
        /// </summary>
        /// <param name="separator">Language-specific decimal separator</param>
        /// <param name="d">Value to be scrutinised</param>
        /// <returns>Number of insignificant zeros after decimal separator.
        /// </returns>
        private static short FindSignificantsAfterDecimal(char separator,
            double d)
        {
            if (d == 0) return 1;
            else
            {
                String value = ConvertToString(d);

                short separatorAt = FindDecimalSeparatorPosition(value);

                if (separatorAt > -1) value = value.Substring(separatorAt + 1);

                short eAt = (short) value.IndexOf(Common.EXPONENT);

                if ((separatorAt == -1) && (eAt == -1)) return 0;
                else if (eAt > 0) value = value.Substring(0, eAt);

                long longValue = Convert.ToInt64(value, invC);

                if (longValue == 0) return 0;
                else if (Math.Abs(d) < 1)
                {
                    value = Convert.ToString(longValue, invC);

                    if (value.Length >= 15)
                    {
                        return (byte)Convert.ToString(longValue, invC).Length;
                    }
                    else return (byte)(value.Length);
                }
                else
                {
                    if (value.Length >= 15) return (byte)(value.Length - 1);
                    else return (byte)(value.Length);
                }
            }
        }

        /// <summary>
        /// Determines the number of significant digits after the decimal
        /// separator knowing the total number of significant digits and
        /// the number before the decimal separator.
        /// </summary>
        /// <param name="significantsBefore">
        /// Number of significant digits before separator
        /// </param>
        /// <param name="significantDigits">
        /// Number of all significant digits
        /// </param>
        /// <returns>
        /// Number of significant decimals after the separator
        /// </returns>
        private static short FindSignificantsAfterDecimal(
            short significantsBefore,
            short significantDigits)
        {
            short significantsAfter =
                (short)(significantDigits - significantsBefore);

            return (short)((significantsAfter > 0) ? significantsAfter : 0);
        }

        /// <summary>
        /// Determines the number of digits before the decimal point.
        /// </summary>
        /// <param name="separator">
        /// Language-specific decimal separator
        /// </param>
        /// <param name="value">Value to be scrutinised</param>
        /// <returns>
        /// Number of digits before the decimal separator
        /// </returns>
        private static short FindSignificantsBeforeDecimal(char separator,
            double d)
        {
            String value = Convert.ToString(d, invC);

            // Return immediately, if result is clear: Special handling at
            // crossroads of floating point and exponential numbers:
            if ((d == 0) || (Math.Abs(d) >= E_TO_DOUBLE) && (Math.Abs(d) < 1))
            {
                return 0;
            }
            else if ((Math.Abs(d) > 0) && (Math.Abs(d) < E_TO_DOUBLE)) return 1;
            else
            {
                short significants = 0;

                for (short s = 0; s < value.Length; s++)
                {
                    if (IsDecimalSeparator(value[s])) break;
                    else if (value[s] != Common.DASH) significants++;
                }

                return significants;
            }
        }

        /// <summary>
        /// Returns the exponent part of the double number.
        /// </summary>
        /// <param name="d">Value of which the exponent is of interest</param>
        /// <returns>Exponent of the number or zero.</returns>
        private static short FindExponent(double d)
        {
            return short.Parse(FindExponent(Convert.ToString(d, invC)), invC);
        }

        /// <summary>
        /// Finds the exponent of a number.
        /// </summary>
        /// <param name="value">
        /// Value where an exponent is to be searched
        /// </param>
        /// <returns>Exponent, if it exists, or "0".</returns>
        private static String FindExponent(String value)
        {
            short eAt = (short)(value.IndexOf(Common.EXPONENT));

            if (eAt < 0) return Common.ZERO;
            else
            {
                return Convert.ToString
                    (short.Parse(value.Substring(eAt + 1)), invC);
            }
        }

        /// <summary>
        /// Finds the mantissa of a number.
        /// </summary>
        /// <param name="separator">
        /// Language-specific decimal separator
        /// </param>
        /// <param name="value">Value where the mantissa is to be found</param>
        /// <returns>Mantissa of the number</returns>
        private static String FindMantissa(char separator,
            String value)
        {
            short eAt = (short)(value.IndexOf(Common.EXPONENT));

            if (eAt > -1) value = value.Substring(0, eAt);

            if (FindDecimalSeparatorPosition(value) == -1) value += ".0";

            return value;
        }

        /// <summary>
        /// Retrieves the digits of the value only
        /// </summary>
        /// <param name="d">Number</param>
        /// <returns>The digits only</returns>
        private static String RetrieveDigits(double d)
        {
            double dValue = d;
            short exponent = FindExponent(d);
            StringBuilder value = new StringBuilder();

            if (exponent == 0)
            {
                value.Append(dValue);

                if (value.Length >= MAX_CHARACTERS)
                {
                    value.Clear();

                    if (Math.Abs(dValue) < 1) value.Append("0");

                    // Determine the exponent for a scientific form:
                    exponent = 0;

                    while (((long)dValue != dValue) && (dValue < 1E11))
                    {
                        dValue *= 10;
                        exponent++;
                    }

                    value.Append((long)dValue);

                    while ((long)dValue != dValue)
                    {
                        dValue -= (long)dValue;

                        dValue *= 10;

                        value.Append((long)dValue);
                    }
                }
            }
            else
            {
                double multiplier = Math.Pow(10, -exponent);

                for (short s = 0; (s <= 16) && (exponent != 0); s++)
                {
                    dValue *= multiplier;

                    value.Append((long)dValue);
                    dValue -= (long)dValue;
                    exponent++;
                    multiplier = 10;
                }
            }

            if (value.Length >= MAX_CHARACTERS + 2)
                value.Length = MAX_CHARACTERS + 2;

            return RetrieveDigits(value.ToString());
        }

        /// <summary>
        /// Retrieves the digits of the value only
        /// </summary>
        /// <param name="number">Value to be scrutinised</param>
        /// <returns>The digits only</returns>
        private static String RetrieveDigits(String number)
        {
            // Strip off exponent part, if it exists:
            short eAt = (short)number.IndexOf(Common.EXPONENT);

            if (eAt > -1) number = number.Substring(0, eAt);

            return number.Replace(Convert.ToString(Common.DASH), "").Replace(
                Convert.ToString(Common.COMMA), "").Replace(
                Convert.ToString(Common.PERIOD), "");
        }

        /// <summary>
        /// Inserts the decimal separator at the right place
        /// </summary>
        /// <param name="dValue">Number</param>
        /// <param name="value">
        /// String variable, where the separator is to be added.
        /// </param>
        private static void InsertSeparator(double dValue, StringBuilder value)
        {
            short separatorAt = (short)Convert.ToString((long)dValue).Length;

            if (separatorAt < value.Length)
                value.Insert(separatorAt, Common.PERIOD);
        }

        /// <summary>
        /// Calculates the power of the base to the exponent without changing
        /// the least-significant digits of a number.
        /// </summary>
        /// <param name="basis"></param>
        /// <param name="exponent">basis to power of exponent</param>
        /// <returns></returns>
        public static double Power(int basis, short exponent)
        {
            return Power((short)basis, exponent);
        }

        /// <summary>
        /// Calculates the power of the base to the exponent without changing
        /// the least-significant digits of a number.
        /// </summary>
        /// <param name="basis"></param>
        /// <param name="exponent"></param>
        /// <returns>basis to power of exponent</returns>
        public static double Power(short basis, short exponent)
        {
            if (basis == 0) return (exponent != 0) ? 1 : 0;   
            else
            {
                if (exponent == 0) return 1;
                else
                {
                    // The Math method power does change the least significant
                    // digits after the decimal separator and is therefore
                    // useless.
                    long result = 1;
                    short s = 0;

                    if (exponent > 0)
                    {
                        for (; s < exponent; s++) result *= basis;
                    }
                    else if (exponent < 0)
                    {
                        for (s = exponent; s < 0; s++) result /= basis;
                    }

                    return result;
                }
            }
        }

        /// <summary>
        /// Rounds a number to the decimal places.
        /// </summary>
        /// <param name="d">Number to be rounded</param>
        /// <param name="separator">
        /// Language-specific decimal separator
        /// </param>
        /// <param name="significantsAfter">
        /// Number of decimal places after the separator
        /// </param>
        /// <returns>Rounded number to the requested decimal places</returns>
        public static double Round(char separator,
            double d,
            short significantsAfter)
        {
            if (d == 0) return 0;
            else
            {
                double constant = Power(10, significantsAfter);
                short dsExponent = FindExponent(d);

                short exponent = dsExponent;

                double value = d*constant*Math.Pow(10, -exponent);
                String exponentSign = (exponent < 0)
                    ? Convert.ToString(Common.DASH) : "";

                if (exponent != 0)
                {
                    exponent = (short)Math.Abs(exponent);

                    value = Round(value);
                }
                else
                {
                    while (FindSignificantsBeforeDecimal(separator, value)
                        < significantsAfter)
                    {
                        constant *= 10;
                        value *= 10;
                    }

                    value = Round(value)/constant;
                }

                // Power method cannot be used, as the exponentiated number may
                // exceed the maximal long value.
                exponent -= (short)(Math.Sign(dsExponent)*
                    (FindSignificantDigits(separator, value, significantsAfter)
                    - 1));
            
                if (dsExponent != 0)
                {
                    String strValue = Convert.ToString(value, invC);

                    short separatorAt = FindDecimalSeparatorPosition(strValue);

                    if (separatorAt > -1)
                    {
                        strValue = strValue.Substring(0, separatorAt);
                    }

                    strValue += Common.EXPONENT + exponentSign
                        + Convert.ToString(exponent);

                    value = double.Parse(strValue, invC);
                }
            
                return value;
            }
        }

        /// <summary>
        /// Rounds a number according to mathematical rules.
        /// </summary>
        /// <param name="d">Number to be rounded</param>
        /// <returns>Rounded number</returns>
        public static double Round(double d)
        {
            return (long)(d + .5);
        }

        /// <summary>
        /// Converts a double value to a string such that it reflects the double
        /// format (without converting it to a scientific format by itself, as
        /// it is the case with Convert.ToString(double, invC)).
        /// </summary>
        /// <param name="d">Value to be converted</param>
        /// <returns>Same format value as a string</returns>
        public static String ConvertToString(double d)
        {
            double dValue = d;
            StringBuilder value = new StringBuilder();

            if (Math.Sign(dValue) == -1) value.Append(Common.DASH);

            if ((dValue > 1E-5) && (dValue < 1E-4))
            {
                value.Append("0");

                while ((long)dValue == 0)
                {
                    dValue *= 10;

                    if (dValue >= 1) break;

                    value.Append(Convert.ToString((long)dValue));
                }
            }

            short exponent = FindExponent(d);

            if (exponent != 0)
            {
                value.Append(RetrieveDigits(dValue));
                InsertSeparator(dValue, value);
                value.Append(Common.EXPONENT);
                value.Append(exponent);
            }
            else
            {
                value.Append(RetrieveDigits(dValue));

                InsertSeparator(dValue, value);

                if (value.Length > MAX_CHARACTERS + 3)
                {
                    value.Length = MAX_CHARACTERS + 3;
                }
            }

            return value.ToString();
        }

        /// <summary>
        /// Rounds to a fixed number of significant digits.
        /// </summary>
        /// <param name="d">Number to be rounded</param>
        /// <param name="significantDigits">
        /// Requested number of significant digits
        /// </param>
        /// <param name="separator">
        /// Language-specific decimal separator
        /// </param>
        /// <returns>Rounded number</returns>
        public static String RoundToString(char separator,
            double d,
            short significantDigits)
        {
            // Number of significants that *are* before the decimal separator:
            short significantsBefore =
                FindSignificantsBeforeDecimal(separator, d);
            // Number of decimals that *should* be after the decimal separator:
            short significantsAfter = FindSignificantsAfterDecimal(
                    significantsBefore, significantDigits);
            // Round to the specified number of digits after decimal separator:
            double rounded = Maths.Round(separator, d, significantsAfter);

            String exponent = FindExponent(Convert.ToString(rounded, invC));
            String mantissa = FindMantissa(separator, 
                            Convert.ToString(rounded, invC));

            double dMantissa = double.Parse(mantissa, invC);
            StringBuilder result = new StringBuilder(mantissa);
            // Determine the significant digits in this number:
            short significants = FindSignificantDigits(separator, dMantissa,
                significantsAfter);
            // Add lagging zeros, if necessary:
            if (significants <= significantDigits)
            {
                if (significantsAfter != 0)
                {
                    result.Append(strZeros.Substring(0,
                        CalculateMissingSignificantZeros(separator,
                            dMantissa, significantsAfter)));
                }
                else
                {
                    // Cut off the decimal separator & after decimal digits:
                    short decimalValue = (short) result.ToString().IndexOf(
                            Convert.ToString(separator));
                
                    if (decimalValue > -1) result.Length = decimalValue;
                }
            }
            else if (significantsBefore > significantDigits)
            {
                d /= Power(10, (short)(significantsBefore - significantDigits));

                d = Round(d);
            
                short digits = (short)(significantDigits + ((d < 0) ? 1 : 0));
            
                String strD = d.ToString().Substring(0, digits);
            
                result.Length = 0;
                result.Append(strD + strZeros.Substring(0,
                        significantsBefore - significantDigits));
            }
        
            if (short.Parse(exponent, invC) != 0)
            {
                result.Append(Common.EXPONENT + exponent);
            }
        
            return result.ToString();
        } // public static String RoundToString(…)

        /// <summary>
        /// Rounds to a fixed number of significant digits.
        /// </summary>
        /// <param name="separator">
        /// Language-specific decimal separator
        /// </param>
        /// <param name="significantDigits">
        /// Requested number of significant digits
        /// </param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static String RoundToString(char separator,
                float value,
                int significantDigits)
        {
            return RoundToString(separator, (double)value,
                (short)significantDigits);
        }
    }   // public class Maths
}

对软件进行广泛测试对于代码质量至关重要。说代码已经过测试并没有提供太多信息。问题在于测试了什么。虽然不是这种情况,但通常也需要知道在哪里(在哪个环境中)进行了测试,以及如何测试,即测试顺序。以下是用于测试 Maths 类的代码。

using System;
using System.Collections.Generic;

namespace ConsoleApplicationCommons
{
    class TestCommon
    {
        /// <summary>
        /// Test for the common functionality
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            // Test rounding
            List<double> values = new List<double>();

            values.Add(0.0);
            AddValue(1.4012984643248202e-45, values);
            AddValue(1.999999757e-5, values);
            AddValue(1.999999757e-4, values);
            AddValue(1.999999757e-3, values);
            AddValue(0.000640589, values);
            AddValue(0.3396899998188019, values);
            AddValue(0.34, values);
            AddValue(7.07, values);
            AddValue(118.188, values);
            AddValue(118.2, values);
            AddValue(123.405009, values);
            AddValue(30.76994323730469, values);
            AddValue(130.76994323730469, values);
            AddValue(540, values);
            AddValue(12345, values);
            AddValue(123456, values);
            AddValue(540911, values);
            AddValue(9.223372036854776e56, values);

            const short SIGNIFICANTS = 5;
        
            foreach (double element in values)
            {
                Console.Out.WriteLine("Maths.Round('" + Common.PERIOD + "', "
                    + Convert.ToString(element, Maths.invC) + ", "
                    + SIGNIFICANTS + ") = " + Maths.RoundToString
                        (Common.PERIOD, element, SIGNIFICANTS));
            }

            Console.In.Read();
        }

        /// <summary>
        /// Method that adds a negative and a positive value
        /// </summary>
        /// <param name="d"></param>
        /// <param name="values"></param>
        private static void AddValue(double d, List<double> values)
        {
            values.Add(-d);
            values.Add(d);
        }
    } // class TestCommon
}

你改进后的代码结果应该与我得到的结果一致。

Maths.Round('.', 0, 5) = 0.00000
Maths.Round('.', -1.40129846432482E-45, 5) = -1.4012E-45
Maths.Round('.', 1.40129846432482E-45, 5) = 1.4013E-45
Maths.Round('.', -1.999999757E-05, 5) = -1.9999E-5
Maths.Round('.', 1.999999757E-05, 5) = 2.0000E-5
Maths.Round('.', -0.0001999999757, 5) = -0.00019999
Maths.Round('.', 0.0001999999757, 5) = 0.00020000
Maths.Round('.', -0.001999999757, 5) = -0.0019999
Maths.Round('.', 0.001999999757, 5) = 0.0020000
Maths.Round('.', -0.000640589, 5) = -0.00064058
Maths.Round('.', 0.000640589, 5) = 0.00064059
Maths.Round('.', -0.339689999818802, 5) = -0.33968
Maths.Round('.', 0.339689999818802, 5) = 0.33969
Maths.Round('.', -0.34, 5) = -0.33999
Maths.Round('.', 0.34, 5) = 0.34000
Maths.Round('.', -7.07, 5) = -7.0699
Maths.Round('.', 7.07, 5) = 7.0700
Maths.Round('.', -118.188, 5) = -118.18
Maths.Round('.', 118.188, 5) = 118.19
Maths.Round('.', -118.2, 5) = -118.19
Maths.Round('.', 118.2, 5) = 118.20
Maths.Round('.', -123.405009, 5) = -123.40
Maths.Round('.', 123.405009, 5) = 123.41
Maths.Round('.', -30.7699432373047, 5) = -30.769
Maths.Round('.', 30.7699432373047, 5) = 30.770
Maths.Round('.', -130.769943237305, 5) = -130.76
Maths.Round('.', 130.769943237305, 5) = 130.77
Maths.Round('.', -540, 5) = -539.99
Maths.Round('.', 540, 5) = 540.00
Maths.Round('.', -12345, 5) = -12344
Maths.Round('.', 12345, 5) = 12345
Maths.Round('.', -123456, 5) = -123450
Maths.Round('.', 123456, 5) = 123460
Maths.Round('.', -540911, 5) = -540900
Maths.Round('.', 540911, 5) = 540910
Maths.Round('.', -9.22337203685478E+56, 5) = -9.2233E56
Maths.Round('.', 9.22337203685478E+56, 5) = 9.2234E56

如果你想与 C++ 进行比较,请将其与同一个 示例 进行比较。如果你想将 C# 与 Java 进行比较,请查看 舍入数字示例

华夏公益教科书