Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将十进制小数舍入到C#中的特定分数?_C#_.net_Algorithm_Math - Fatal编程技术网

如何将十进制小数舍入到C#中的特定分数?

如何将十进制小数舍入到C#中的特定分数?,c#,.net,algorithm,math,C#,.net,Algorithm,Math,在C#中,将数字四舍五入很容易: Math.Round(1.23456, 4); // returns 1.2346 但是,我想对一个数字进行四舍五入,使数字的小数部分四舍五入到预定义小数部分中最接近的小数部分(例如1/8),并且我试图找出.NET库是否已经内置了此功能 例如,如果我想把一个十进制数四舍五入到一个八分之一,那么我想调用如下内容: Math.RoundFractional(1.9, 8); // and have this yield 1.875 Math.RoundFracti

在C#中,将数字四舍五入很容易:

Math.Round(1.23456, 4); // returns 1.2346
但是,我想对一个数字进行四舍五入,使数字的小数部分四舍五入到预定义小数部分中最接近的小数部分(例如1/8),并且我试图找出.NET库是否已经内置了此功能

例如,如果我想把一个十进制数四舍五入到一个八分之一,那么我想调用如下内容:

Math.RoundFractional(1.9, 8); // and have this yield 1.875
Math.RoundFractional(1.95, 8); // and have this yield 2.0
所以第一个参数是我要舍入的数字,第二个参数指示舍入分数。因此,在本例中,四舍五入后,小数点后的数字只能是八个值中的一个:.000、.125、.250、.375、.500、.625、.750、.875

问题是:这个函数是否内置在.NET的某个地方?如果没有,是否有人有一个指向资源的链接来解释如何解决此问题?

您可以这样做:

Math.Round(n * 8) / 8.0

不知道它是否内置在.NET中,但我只想:

Math.Round(x * 8, 0) / 8;
把它四舍五入到最近的第八位


用你最喜欢的数字代替其他的“解决方案”。

这是一个迟来的回复,但对于任何想寻找更全面的解决方案来转换双精度的人来说,正如原始帖子所描述的那样。下面是一个静态类,它为double提供扩展方法,以各种方式实现这一点

using System;

/// <summary>
/// Author: Aniceto Moreno Jr
/// Email:  amorenojr@outlook.com
/// Date:   03/23/2020
/// </summary>
public static class DoubleExtensions
{
    /// <summary>
    /// Rounds the value to the nearest increment. 
    /// Assumes mid-point rounding, value >= 0.5 rounds up, value < 0.5 rounds down.
    /// </summary>
    /// <param name="Value"></param>
    /// <param name="increment">Enter the increment value to round toward.</param>
    /// <returns>Returns the value rounded to the nearest increment value.</returns>
    public static double RoundToNearest(this double Value, double increment)
    {
        // Returning the value rounded to the nearest increment value.
        return Math.Round(Value * Math.Pow(increment, -1), 0) * increment;
    }

    /// <summary>
    /// Rounds down the value to the nearest increment. 
    /// </summary>
    /// <param name="Value"></param>
    /// <param name="increment">Enter the increment value to round down toward.</param>
    /// <returns>Returns the value rounded down to the nearest increment value.</returns>
    public static double FloorToNearest(this double Value, double increment)
    {
        // Returning the value rounded down to the nearest increment value.
        return Math.Floor(Value * Math.Pow(increment, -1)) * increment;
    }

    /// <summary>
    /// Rounds up the value to the nearest increment. 
    /// </summary>
    /// <param name="Value"></param>
    /// <param name="increment">Enter the increment value to round up toward.</param>
    /// <returns>Returns the value rounded up to the nearest increment value.</returns>
    public static double CeilingToNearest(this double Value, double increment)
    {
        // Returning the value rounded up to the nearest increment value.
        return Math.Ceiling(Value * Math.Pow(increment, -1)) * increment;
    }

    /// <summary>
    /// Rounds the value down to the nearest imperial fractional increment
    /// and converts the value into an Inch-Fraction (IF) string. 
    /// Note: Assumes value is in inches and does not convert to Feet-Inch-Fraction (FIF)
    /// </summary>
    /// <param name="Value"></param>
    /// <param name="maxDenominator">Enter the maximum denominator to round toward (i.e. 1/16 --> 16)</param>
    /// <returns>Returns the value rounded down to the nearest increment value based on the maxDenominator.</returns>
    public static string FloorToInchFraction(this double Value, int maxDenominator)
    {
        // Returning the rounded value converted into an Inch-Fraction (IF) string.
        return Value.FloorToNearest(Math.Pow(maxDenominator, -1)).ToInchFraction(maxDenominator);
    }

    /// <summary>
    /// Rounds the value up to the nearest imperial fractional increment
    /// and converts the value into an Inch-Fraction (IF) string. 
    /// Note: Assumes value is in inches and does not convert to Feet-Inch-Fraction (FIF)
    /// </summary>
    /// <param name="Value"></param>
    /// <param name="maxDenominator">Enter the maximum denominator to round toward (i.e. 1/16 --> 16)</param>
    /// <returns>Returns the value rounded up to the nearest increment value based on the maxDenominator.</returns>
    public static string CeilingToInchFraction(this double Value, int maxDenominator)
    {
        // Returning the rounded value converted into a fraction string.
        return Value.CeilingToNearest(Math.Pow(maxDenominator, -1)).ToInchFraction(maxDenominator);
    }

    /// <summary>
    /// Rounds the value to the nearest increment value based on the maximum denominator specified.
    /// Assumes mid-point rounding, value >= 0.5 rounds up, value < 0.5 rounds down.
    /// </summary>
    /// <param name="Value"></param>
    /// <param name="maxDenominator">Enter the maximum denominator to round toward (i.e. 1/16 --> 16)</param>
    /// <returns>Returns the value rounded to the nearest increment value based on the maxDenominator.</returns>
    public static string ToInchFraction(this double Value, int maxDenominator)
    {
        // Calculating the nearest increment of the value
        // argument based on the denominator argument.
        double incValue = Value.RoundToNearest(Math.Pow(maxDenominator, -1));

        // Identifying the whole number of the argument value.
        int wholeValue = (int)Math.Truncate(incValue);

        // Calculating the remainder of the argument value and the whole value.
        double remainder = incValue - wholeValue;

        // Checking for the whole number case and returning if found.
        if (remainder == 0.0) { return wholeValue.ToString() + (char)34; }

        // Iterating through the exponents of base 2 values until the
        // maximum denominator value has been reached or until the modulus
        // of the divisor.
        for (int i = 1; i < (int)Math.Log(maxDenominator, 2) + 1; i++)
        {
            // Calculating the denominator of the current iteration
            double denominator = Math.Pow(2, i);

            // Calculating the divisor increment value
            double divisor = Math.Pow(denominator, -1);

            // Checking if the current denominator evenly divides the remainder
            if ((remainder % divisor) == 0.0) // If, yes
            {
                // Calculating the numerator of the remainder 
                // given the calculated denominator
                int numerator = Convert.ToInt32(remainder * denominator);

                // Returning the resulting string from the conversion.
                return (wholeValue > 0 ? wholeValue.ToString() + "-" : "") + numerator.ToString() + "/" + ((int)denominator).ToString() + (char)34;
            }
        }

        // Returns Error if something goes wrong.
        return "Error";
    }

    /// <summary>
    /// Rounds the value down to the nearest imperial fractional increment
    /// and converts the value into an Feet-Inch-Fraction (FIF) string. 
    /// </summary>
    /// <param name="Value"></param>
    /// <param name="maxDenominator">Enter the maximum denominator to round toward (i.e. 1/16 --> 16)</param>
    /// <returns>Returns the value rounded down to the nearest increment value based on the maxDenominator.</returns>
    public static string FloorToFeetInchFraction(this double Value, int maxDenominator)
    {
        // Returning the rounded value converted into an Feet-Inch-Fraction (FIF) string.
        return Value.FloorToNearest(Math.Pow(maxDenominator, -1)).ToFeetInchFraction(maxDenominator);
    }

    /// <summary>
    /// Rounds the value up to the nearest imperial fractional increment
    /// and converts the value into an Feet-Inch-Fraction (FIF) string. 
    /// </summary>
    /// <param name="Value"></param>
    /// <param name="maxDenominator">Enter the maximum denominator to round toward (i.e. 1/16 --> 16)</param>
    /// <returns>Returns the value rounded up to the nearest increment value based on the maxDenominator.</returns>
    public static string CeilingToFeetInchFraction(this double Value, int maxDenominator)
    {
        // Returning the rounded value converted into a fraction string.
        return Value.CeilingToNearest(Math.Pow(maxDenominator, -1)).ToFeetInchFraction(maxDenominator);
    }

    /// <summary>
    /// Rounds the value to the nearest increment value based on the maximum denominator specified.
    /// Assumes mid-point rounding, value >= 0.5 rounds up, value < 0.5 rounds down.
    /// </summary>
    /// <param name="Value"></param>
    /// <param name="maxDenominator">Enter the maximum denominator to round toward (i.e. 1/16 --> 16)</param>
    /// <returns>Returns the value rounded to the nearest increment value based on the maxDenominator.</returns>
    public static string ToFeetInchFraction(this double Value, int maxDenominator)
    {
        // Calculating the nearest increment of the value
        // argument based on the denominator argument.
        double incValue = Value.RoundToNearest(Math.Pow(maxDenominator, -1));

        // Calculating the remainder of the argument value and the whole value.
        double FeetInch = Math.Truncate(incValue) / 12.0;

        // Calculating the remainder of the argument value and the whole value.
        int Feet = (int)Math.Truncate(FeetInch);

        // Calculating remaining inches.
        incValue -= (double)(Feet * 12.0);

        // Returns the feet plus the remaining amount converted to inch fraction.
        return (Feet > 0 ? Feet.ToString() + (char)39 + " " : "") + incValue.ToInchFraction(maxDenominator);
    }
}
double testValue0 = 1.0625; // 1―1/16"
Console.WriteLine(testValue0.ToInchFraction(32)); // 1―1/16"

double testValue1 = 1.515625; // 1―33/64"
Console.WriteLine(testValue1.CeilingToInchFraction(16)); // 1―9/16"

double testValue2 = 1.03125; // 1―1/32"
Console.WriteLine(testValue2.FloorToInchFraction(16)); // 1"

double testValue3 = 5 / 25.4; // 5 mm = 0.1969 in
Console.WriteLine(testValue3.ToInchFraction(32)); // 3/16"
Console.WriteLine(testValue3.ToInchFraction(64)); // 13/64"