繁体   English   中英

在 C# 中截断双精度值的位数

[英]Truncate number of digit of double value in C#

如何在 C# 中截断 double 值的前导数字,我试过 Math.Round(doublevalue,2) 但没有给出 require 结果。 我在数学课上没有找到任何其他方法。

例如,我的值是 12.123456789,而我只需要 12.12。

编辑:有人指出,这些方法是围绕值而不是截断 很难真正截断double值,因为它实际上不在正确的基数中……但截断decimal值更可行。

您应该使用适当的格式字符串,自定义标准,例如

string x = d.ToString("0.00");

要么

string x = d.ToString("F2");

值得注意的是,double 值本身并不“知道”它有多少个小数位。 只有当您将其转换为字符串时,这样做才真正有意义。 使用Math.Round将得到最接近的双重价值x.xx00000 (如果你明白我的意思),但它几乎肯定不会是精确值x.xx00000由于道路二进制浮点类型的工作。

如果您需要将其用于字符串格式以外的任何其他内容,则应考虑改用decimal 值实际上代表什么?

我有关于 .NET 中的二进制浮点十进制浮点的文章,您可能会发现它们很有用。

你尝试过什么? 它按我的预期工作:

double original = 12.123456789;

double truncated = Math.Truncate(original * 100) / 100;

Console.WriteLine(truncated);    // displays 12.12

这段代码....

double x = 12.123456789;
Console.WriteLine(x);
x = Math.Round(x, 2);
Console.WriteLine(x);

返回这个....

12.123456789
12.12

你想要的结果是什么不同?

如果您想将该值保留为双精度值,并且只是去掉第二个小数位后的任何数字而不实际舍入该数字,那么您只需从您的数字中减去 0.005,这样该舍入就可以工作。 例如。

double x = 98.7654321;
Console.WriteLine(x);
double y = Math.Round(x - 0.005, 2);
Console.WriteLine(y);

产生这个...

98.7654321
98.76

这可以工作(虽然没有测试):

public double RoundDown(this double value, int digits)
{
     int factor = Math.Pow(10,digits);

     return Math.Truncate(value * factor) / factor;
}

然后你只需像这样使用它:

double rounded = number.RoundDown(2);
double original = 12.123456789;  

double truncated = Truncate(original, 2);  

Console.WriteLine(truncated.ToString());
// or 
// Console.WriteLine(truncated.ToString("0.00"));
// or 
// Console.WriteLine(Truncate(original, 2).ToString("0.00"));


public static double Truncate(double value, int precision)
{
    return Math.Truncate(value * Math.Pow(10, precision)) / Math.Pow(10, precision);
}

我敢肯定还有更多的 .netty 存在,但为什么不只是:-

double truncVal = Math.Truncate(val * 100) / 100;
double remainder = val-truncVal;

怎么样:

double num = 12.12890;
double truncatedNum = ((int)(num * 100))/100.00;

使用 Math.Truncate(double) 有很多答案。 但是,使用 Math.Truncate(double) 的方法可能会导致不正确的结果。 例如,它将返回 5.01 截断 5.02,因为 double 值的乘法不能精确地工作并且 5.02*100=501.999999999999994

5.02*100=501.99999999999994

如果您真的需要这种精度,请考虑在截断之前转换为 Decimal。

public static double Truncate(double value, int precision)
{
    decimal power = (decimal)Math.Pow(10, precision);
    return (double)(Math.Truncate((decimal)value * power) / power);
}

尽管如此,这种方法还是慢了大约 10 倍。

object number = 12.123345534;   
string.Format({"0:00"},number.ToString());

如果您希望小数点后有两个点而不舍入数字,则以下应该有效

string doubleString = doublevalue.ToString("0.0000"); //To ensure we have a sufficiently lengthed string to avoid index issues
Console.Writeline(doubleString
             .Substring(0, (doubleString.IndexOf(".") +1) +2)); 

substring 的第二个参数是计数,IndexOf 返回从零开始的索引,因此我们必须在添加 2 个十进制值之前对其加 1。

这个答案假设值不应该四舍五入

对于 vb.net 使用这个扩展:

Imports System.Runtime.CompilerServices

Module DoubleExtensions

    <Extension()>
    Public Function Truncate(dValue As Double, digits As Integer)

        Dim factor As Integer
        factor = Math.Pow(10, digits)

        Return Math.Truncate(dValue * factor) / factor

    End Function
End Module

这可能是十进制? 我写了我自己的因为在网上努力寻找答案。 这段代码可能不是完全证明,因为我缺乏完全证明它的经验。 最终会将此方法重建为简单而出色的方法,以便以更少的步骤完成工作,同时提高整体稳健性。 您可以轻松地将其转换为间距计数的输入。 但我不能保证它会在十二月二日以外的情况下正常运行。 不喜欢简单的输入......似乎喜欢使用 000.000,因为我正在处理 0000.000 的重量。 此外,计算后用此四舍五入价格。

private decimal TruncateToTwoDecimals(string value)
        {

            int error_ReturnZeroIfThisIsOne = 0;
            int tempArrayLength = value.Length;
            char[] tempArray = new char[tempArrayLength];

            int startCount = 0; //starts the counter when it hits punctuation
            int newCounter = 0; //counts twice to ensure only two decimal places after the comma/period
            int nextArraySize = 1; //gets the size spec ready for the return array/next array (needs to be + 1)

            int tempArrayCurrentIndex = 0;
            foreach (Char thisChar in value)
            {
                tempArray[tempArrayCurrentIndex] = thisChar;
                tempArrayCurrentIndex++;
            }


            for (int i = 0; i < tempArrayLength; i++)
            {

                if (tempArray[i].ToString() == "," || tempArray[i].ToString() == ".")
                {
                    startCount = 1;
                }
                if (startCount == 1)
                {
                    newCounter++;
                }


                if (newCounter > 2)
                {
                    break;
                }
                nextArraySize++;
            }

            char[] returnArray = new char[nextArraySize];
            int tempErrorCheckBelow = 0;
            for (int i = 0; i < nextArraySize; i++)
            {


                try
                {
                    returnArray[i] = tempArray[i]; //left array will read [i] till the spot in right array where second decimal and ignore the rest. snip snip
                }
                catch (Exception)
                {
                    if (tempErrorCheckBelow == 2)
                    {
                        MessageBox.Show("OutOfBounds", "Error_ArrayIndex Out Of Bounds @TTTD");
                    }
                    returnArray[i] = Convert.ToChar("0");
                    tempErrorCheckBelow++;
                }

            }

            if (tempArrayLength < 1)
            {

                error_ReturnZeroIfThisIsOne++;

                string tempString = "0.0";
                try
                {
                    decimal tempDecimal = Decimal.Parse(tempString);
                    return tempDecimal;
                }
                catch (Exception)
                {

                    MessageBox.Show("Error_input String received Incorrect Format @TTTD");
                    return 0.00m;
                }
            }
            else
            {

                error_ReturnZeroIfThisIsOne++;

                string tempString = " ";
                tempString = new string(returnArray);
                try
                {
                    decimal tempDecimal = Decimal.Parse(tempString);
                    return tempDecimal;
                }
                catch (Exception)
                {
                    MessageBox.Show("Error_inputString _0_ @TTTD");
                    return 0m;

                }
            }



        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM