我有一个变量代表某个给定单位的数量:
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,我知道课程"数量"这不是存储信息的好方法 - 但这受到我的应用程序的输入数据的约束,该数据是非单一的(例如数百万,数十亿等)单位。
答案 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;
}