计算System.Decimal precision及规模 [英] Calculate System.Decimal Precision and Scale

查看:180
本文介绍了计算System.Decimal precision及规模的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有System.Decimal数。

Suppose that we have a System.Decimal number.

有关说明,让我们一个其toString()方法重新presentation如下:

For illustration, let's take one whose ToString() representation is as follows:

d.ToString() = "123.4500"

以下,可以说这个小数。对于我们的目的,程定义为数字在小数点右侧的数目。有效的规模类似,但忽略了发生在小数部分的任何尾随零。 (换言之,这些参数被定义如SQL小数加上一些额外的参数以考虑在小数部分尾随零的System.Decimal概念。)

The following can be said about this Decimal. For our purposes here, scale is defined as the number of digits to the right of the decimal point. Effective scale is similar but ignores any trailing zeros that occur in the fractional part. (In other words, these parameters are defined like SQL decimals plus some additional parameters to account for the System.Decimal concept of trailing zeros in the fractional part.)

  • precision:7
  • 比例:4
  • 在有效precision:5
  • EffectiveScale:2

给定一个任意System.Decimal,我怎么能计算出这四个参数,高效率,没有转换为字符串,并检查字符串?该解决方案可能需要Decimal.GetBits。

Given an arbitrary System.Decimal, how can I compute all four of these parameters efficiently and without converting to a String and examining the String? The solution probably requires Decimal.GetBits.

更多的例子:

Examples Precision  Scale  EffectivePrecision  EffectiveScale
0        1 (?)      0      1 (?)               0
0.0      2 (?)      1      1 (?)               0
12.45    4          2      4                   2
12.4500  6          4      4                   2
770      3          0      3                   0

(?)或者跨preting这些precisions为零就可以了。

(?) Alternatively interpreting these precisions as zero would be fine.

推荐答案

是的,你需要使用 Decimal.GetBits 。不幸的是,你再有一个96位整数的工作,有在.NET中没有简单的整数类型,它处理96位。在另一方面,它可能是你可以使用十进制本身...

Yes, you'd need to use Decimal.GetBits. Unfortunately, you then have to work with a 96-bit integer, and there are no simple integer type in .NET which copes with 96 bits. On the other hand, it's possible that you could use Decimal itself...

下面是产生相同的数字作为你的例子一些code。希望你觉得它有用:)

Here's some code which produces the same numbers as your examples. Hope you find it useful :)

using System;

public class Test
{
    static public void Main(string[] x)
    {
        ShowInfo(123.4500m);
        ShowInfo(0m);
        ShowInfo(0.0m);
        ShowInfo(12.45m);
        ShowInfo(12.4500m);
        ShowInfo(770m);
    }

    static void ShowInfo(decimal dec)
    {
        // We want the integer parts as uint
        // C# doesn't permit int[] to uint[] conversion,
        // but .NET does. This is somewhat evil...
        uint[] bits = (uint[])(object)decimal.GetBits(dec);


        decimal mantissa = 
            (bits[2] * 4294967296m * 4294967296m) +
            (bits[1] * 4294967296m) +
            bits[0];

        uint scale = (bits[3] >> 16) & 31;

        // Precision: number of times we can divide
        // by 10 before we get to 0        
        uint precision = 0;
        if (dec != 0m)
        {
            for (decimal tmp = mantissa; tmp >= 1; tmp /= 10)
            {
                precision++;
            }
        }
        else
        {
            // Handle zero differently. It's odd.
            precision = scale + 1;
        }

        uint trailingZeros = 0;
        for (decimal tmp = mantissa;
             tmp % 10m == 0 && trailingZeros < scale;
             tmp /= 10)
        {
            trailingZeros++;
        }

        Console.WriteLine("Example: {0}", dec);
        Console.WriteLine("Precision: {0}", precision);
        Console.WriteLine("Scale: {0}", scale);
        Console.WriteLine("EffectivePrecision: {0}",
                          precision - trailingZeros);
        Console.WriteLine("EffectiveScale: {0}", scale - trailingZeros);
        Console.WriteLine();
    }
}

这篇关于计算System.Decimal precision及规模的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆