.net 有什么办法可以得到这个“答案”吗;“有效数字”;一个小数点? 更新

.net 有什么办法可以得到这个“答案”吗;“有效数字”;一个小数点? 更新,.net,decimal,precision,significant-digits,.net,Decimal,Precision,Significant Digits,好的,经过一些调查,在很大程度上要感谢乔恩和汉斯提供的有用的答案,这就是我能够总结出来的。到目前为止,我认为它似乎运作良好。当然,我不会把我的生命押在它的完全正确上 public static int GetSignificantDigitCount(this decimal value) { /* So, the decimal type is basically represented as a fraction of two * integers: a numerator

好的,经过一些调查,在很大程度上要感谢乔恩和汉斯提供的有用的答案,这就是我能够总结出来的。到目前为止,我认为它似乎运作良好。当然,我不会把我的生命押在它的完全正确上

public static int GetSignificantDigitCount(this decimal value)
{
    /* So, the decimal type is basically represented as a fraction of two
     * integers: a numerator that can be anything, and a denominator that is 
     * some power of 10.
     * 
     * For example, the following numbers are represented by
     * the corresponding fractions:
     * 
     * VALUE    NUMERATOR   DENOMINATOR
     * 1        1           1
     * 1.0      10          10
     * 1.012    1012        1000
     * 0.04     4           100
     * 12.01    1201        100
     * 
     * So basically, if the magnitude is greater than or equal to one,
     * the number of digits is the number of digits in the numerator.
     * If it's less than one, the number of digits is the number of digits
     * in the denominator.
     */

    int[] bits = decimal.GetBits(value);

    if (value >= 1M || value <= -1M)
    {
        int highPart = bits[2];
        int middlePart = bits[1];
        int lowPart = bits[0];

        decimal num = new decimal(lowPart, middlePart, highPart, false, 0);

        int exponent = (int)Math.Ceiling(Math.Log10((double)num));

        return exponent;
    }
    else
    {
        int scalePart = bits[3];

        // Accoring to MSDN, the exponent is represented by
        // bits 16-23 (the 2nd word):
        // http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx
        int exponent = (scalePart & 0x00FF0000) >> 16;

        return exponent + 1;
    }
}
不过,我还没有完成这项工作。任何想分享想法的人:非常感谢


原始问题 假设我编写了以下代码:

decimal a = 1.23M;
decimal b = 1.23000M;

Console.WriteLine(a);
Console.WriteLine(b);
以上将输出:

1.23 1.23000 上述产出:

21.729560302171195125816619416 21.729560302171195125816619416 我想问的是:如何编写一个返回
21.73
的方法(因为
123.4M
有四个有效数字)

明确地说:我意识到我可以对两个参数调用
ToString
,计算每个字符串中的有效数字,并使用这个数字对计算结果进行四舍五入。如果可能的话,我正在寻找一种不同的方式

(我还意识到,在处理重要数字的大多数情况下,您可能不需要使用
decimal
类型。但我提出这个问题是因为,正如我在开始时提到的,
decimal
类型似乎包含精度信息,而据我所知,
double
不包含精度信息。)

您可以使用来获取原始数据,并从中计算出来


不幸的是,我现在没有时间编写示例代码——如果您使用的是.NET4,您可能会想使用它来进行一些操作——但希望这能让您顺利完成。计算精度,然后调用Math.Round对原始结果进行取整可能是一个好的开始。

是的,与浮点类型不同,System.Decimal跟踪文本中的位数。这是decimal.Parse()的一项功能,无论是由代码自己执行,还是由编译器在解析程序中的文字时执行。您可以恢复此信息,请在中查看我答案中的代码


在对值进行数学运算后恢复有效位数对我来说是一个漫长的过程。不知道运营商是否保存了它们,请告诉我们您发现了什么

上面的解决方案会很快从床上掉下来,其值为1200,其中有效位数为2,但函数返回4。也许有一种一致的方式来处理这种情况,即检查以确保返回值不包括整数部分中的尾随零,而不包括小数部分。

直到您询问+1,我才知道我想知道这一点!对于其中一些输入,您的函数无法正常工作。例如,-0.012只是2个有效数字,而不是4。@JamesJones显然他指的是有效数字的不同概念,而不是在数学课程中学习的概念。也许“用过的数字”这个名字更有意义。我接受这个答案,尽管我还没有完成我的解决方案,因为它确实给了我我需要的信息。(可悲的是,我希望有一个比
GetBits
更容易访问的东西;但这似乎是我们必须处理的最好的东西!)是的,我很确定这些信息不会被保存。这是有道理的——我的意思是,考虑到像
1M/4M
,它显然应该是
0.25M
而不是
0.3M
。无论如何,我解决了这个问题一点,并提出了一些类似于正在形成的解决方案的东西(我看到你在链接的答案中建议的完全相同的玩弄!)。。。不过,我的代码很难看。如果你有空的话,我会非常感谢你对我在问题顶部的更新的想法。 1.23 1.23000
decimal a = 123.4M;
decimal b = 5.6789M;

decimal x = a / b;

Console.WriteLine(x);
21.729560302171195125816619416