5 Stimmen

Wie runde ich eine Dezimalzahl auf einen bestimmten Bruch in C#?

In C# ist es einfach, eine Zahl zu runden:

Math.Round(1.23456, 4); // returns 1.2346

Ich möchte jedoch eine Zahl so runden, dass der gebrochene Teil der Zahl auf den nächstgelegenen gebrochenen Teil eines vordefinierten Bruchs (z. B. 1/8) rundet, und ich versuche, herauszufinden, ob die .NET-Bibliothek dies bereits eingebaut hat.

Wenn ich also zum Beispiel eine Dezimalzahl auf ein ganzes Achtel runden möchte, dann würde ich etwas aufrufen wie:

Math.RoundFractional(1.9, 8); // and have this yield 1.875
Math.RoundFractional(1.95, 8); // and have this yield 2.0

Der erste Parameter ist also die Zahl, die gerundet werden soll, und der zweite Parameter gibt den Rundungsbruch an. In diesem Beispiel können die Zahlen nach dem Komma nach der Rundung nur einen von acht Werten annehmen: .000, .125, .250, .375, .500, .625, .750, .875

Die Fragen: Ist diese Funktion irgendwo in .NET eingebaut? Wenn nicht, hat jemand einen Link zu einer Ressource, die erklärt, wie man dieses Problem lösen kann?

21voto

Greg Hewgill Punkte 882617

Sie könnten dies tun:

Math.Round(n * 8) / 8.0

6voto

paxdiablo Punkte 809679

Ich weiß nicht, ob es in .NET integriert ist, aber ich würde es einfach tun:

Math.Round(x * 8, 0) / 8;

um sie auf die nächste 8 zu runden.

Ersetzen Sie Ihre Lieblingszahl durch andere "Vorsätze".

0voto

amorenojr Punkte 11

Dies ist eine späte Antwort, aber für diese ist für alle, die für eine umfassendere Lösung zu konvertieren, ein Double wie der ursprüngliche Beitrag beschreibt. Im Folgenden finden Sie eine statische Klasse, die Erweiterungsmethoden für Doubles bietet, um dies auf verschiedene Weise zu erreichen.

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);
    }
}

Beispiele für die Verwendung und Umsetzung:

double testValue0 = 1.0625; // 11/16"
Console.WriteLine(testValue0.ToInchFraction(32)); // 11/16"

double testValue1 = 1.515625; // 133/64"
Console.WriteLine(testValue1.CeilingToInchFraction(16)); // 19/16"

double testValue2 = 1.03125; // 11/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"

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X