因为双倍10 ^ x的结果是Int64?

时间:2016-04-04 10:08:15

标签: c# type-conversion

我有一个变量代表某个给定单位的数量:

enum Unit
{
  Single,
  Thousand,
  Million,
  Billion,
  Trillion
}

public class Quantity()
{

  public double number;
  public Unit numberUnit;

  public Int64 GetNumberInSingleUnits()
  {
    // ???
  }

}

例如,想象

var GDP_Of_America = new Quantiy { number = 16.66, numberUnit = Unit.Trillion };
Int64 gdp = GDP_Of_America.GetNumberinSingleUnits();  // should return 16,660,000,000,000

我的问题基本上是 - 如何实现" GetNumberInSingleUnits"功能? 我不能仅仅乘以一些UInt64因子,例如

        double num = 0.5;
        UInt64 factor = 1000000000000;

        var result = num * factor; // won't work! results in double

由于常规数值运算在double中有效,但结果可能大于有效双精度范围。

我怎么能进行这种转换?

ps,我知道课程"数量"这不是存储信息的好方法 - 但这受到我的应用程序的输入数据的约束,该数据是非单一的(例如数百万,数十亿等)单位。

2 个答案:

答案 0 :(得分:2)

就像我说的那样,decimal可以帮助你:

public enum Unit
{
    Micro = -6, Milli = -3, Centi = -2, Deci = -1,
    One /* Don't really like this name */, Deca, Hecto, Kilo, Mega = 6, Giga = 9
}

public struct Quantity
{
    public decimal Value { get; private set; }

    public Unit Unit { get; private set; }

    public Quantity(decimal value, Unit unit) : 
        this()
    {
        Value = value;
        Unit = unit;
    }

    public decimal OneValue /* This one either */
    {
        get
        {
            return Value * (decimal)Math.Pow(10, (int)Unit);
        }
    }
}

使用decimal s,在您决定将它们转换为long(并注意上溢/下溢)之前,您不会失去很多精确度。

答案 1 :(得分:0)

安东的回答似乎是一个很好的解决方案。 仅仅为了讨论,另一种可能的方式。

我根本不喜欢这个,因为它看起来非常凌乱;但是我认为这个可能会避免不精确,如果这些都是小数问题。

public Int64 GetAsInt64(double number)
{
    // Returns 1 for single units, 3 for thousands, 6 for millions, etc.
    uint e = GetFactorExponent();

    // Converts to scientific notation
    // e.g. number = -1.2345, unit millions to "-1.2345e6"
    string str = String.Format("{0:#,0.###########################}", number) + "e" + e;

    // Parses scientific notation into Int64
    Int64 result = Int64.Parse(str, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent | NumberStyles.AllowThousands);
    return result;
}