我想找到 C# 的最低有效数字位置,decimal
并在该位置设置 1,在所有其他位置设置零。
例如,对于 2m,结果将是 1m。对于 34m,结果将是 1m。对于 0.4m,它将返回 0.1m。对于1200m,我想要100m。
我该怎么做呢?
我可以使用类似于https://stackoverflow.com/a/757266/246622的东西吗?
(编辑:我删除了令人困惑的 2.0m,添加了 1200 的结果)
我想找到 C# 的最低有效数字位置,decimal
并在该位置设置 1,在所有其他位置设置零。
例如,对于 2m,结果将是 1m。对于 34m,结果将是 1m。对于 0.4m,它将返回 0.1m。对于1200m,我想要100m。
我该怎么做呢?
我可以使用类似于https://stackoverflow.com/a/757266/246622的东西吗?
(编辑:我删除了令人困惑的 2.0m,添加了 1200 的结果)
您可以利用 Decimal 的实现细节,它的指数等于小数中有效数字的数量。您可以使用 GetBits() 方法获取指数的值。这使得这个(相当模糊的)代码工作:
public static Decimal SignificantFraction(Decimal d) {
var b = decimal.GetBits(d);
return new decimal(1, 0, 0, false, (byte)((b[3] >> 16) & 0x7fff));
}
请注意,这甚至适用于像 0.0m 这样的极端情况,它会产生 0.1m。您没有指定负值应该发生什么,所以我在构造函数中选择了false。d < 0
如果您希望结果为负,请将其替换为。
这些方面的东西怎么样?
decimal number = 1200m;
decimal result = 1;
decimal tmp = number;
while (tmp % 1 != 0)
{
result /= 10;
tmp *= 10;
}
if (result > 0 && number != 0)
{
tmp = number;
while (tmp % 10 == 0)
{
result *= 10;
tmp /= 10;
}
}
编辑:所以添加了 1200 示例,我的解决方案不再那么整洁了......但我认为它应该可以解决问题
var t = 1.11111000m;
//var t = 134000m;
var tr = t.ToString().Reverse().ToArray();
char[] ca;
if (t % 1 > 0)
ca = tr.SkipWhile(c => c == '0').Select((c, i) => i == 0 ? '1' : c == ',' ? ',' : '0').Reverse().ToArray();
else
{
ca = tr.TakeWhile((c, i) => c == '0' || tr[i - 1] == '0').Reverse().ToArray();
ca[0] = '1';
}
var result = decimal.Parse(new string(ca));