4 回答
TA贡献1725条经验 获得超7个赞
使用这个问题的标记答案:
static void Main()
{
Console.WriteLine("DECIMAL");
decimal dTest = 1.527m;
var dTest2 = dTest;
while(dTest2 < dTest*1.1m)
{
dTest2 = RoundUp(dTest2);
Console.WriteLine(dTest2);
}
Console.WriteLine("FLOAT");
float fTest = 1.527f;
var fTest2 = fTest;
while(fTest2 < fTest*1.1f)
{
fTest2 = RoundUp(fTest2);
Console.WriteLine(fTest2);
}
}
static decimal RoundUp(decimal input)
{
int precision = BitConverter.GetBytes(decimal.GetBits(input)[3])[2];
decimal factor = (decimal)Math.Pow(10,precision-1);
return Math.Ceiling(input*factor)/factor;
}
static float RoundUp(float input)
{
return (float)RoundUp((decimal)input);
}
输出:
DECIMAL
1.53
1.6
2
FLOAT
1.53
1.6
2
TA贡献1818条经验 获得超3个赞
为什么不通过简单的 10 次幂乘法来实现,这可以有效地移动小数点,您可以在其中调用 Math.Ceiling 将数字向上取整。除以 10 的相同幂以将小数点放回原来的位置。
使用decimal.ToString()为“避开”的浮点精度的问题,看到这个博客帖子获取更多信息
var values = new[] { 1.527f, 1.53f, 1.6f, -1.527f };
for (var i = 0; i < values.Length; i++)
{
var val = (decimal)values[i];
var precision = (decimal.GetBits(val)[3] >> 16 & 0xff) - 1;
var power = (decimal)Math.Pow(10, precision);
if (val < 0)
val = Math.Floor(val * power) / power;
else
val = Math.Ceiling(val * power) / power;
Console.WriteLine(val);
}
输出
1.53
1.6
2
-1.53
注意 Math.Pow和Math.Ceiling是对 的操作double,因此强制转换为doublefromfloat
更新计算出它需要舍入到多少小数位并使用小数来“解决”浮点精度问题。
更新 2用于decimal.GetBytes获得数字的精度,而不是执行相当繁琐的文化不变ToString().Splityada yada yada。
更新 3对于负数,从零开始舍入并按位添加& 0xff以去除符号位。
TA贡献1893条经验 获得超10个赞
独立于文化的解决方案:
static double RoundUp(double val)
{
double a = val;
double decimals = a - ((int)a); //Gets only decimals
double pow = Math.Pow(10, decimals.ToString().Length - 3);
a = a * pow; //Multiply by a power of 10 | decimal shift
a = Math.Ceiling(a); //Round up
a = a / pow; //Shift back
return a;
}
并称之为:
var res = RoundUp(1.527); //1.53
res = RoundUp(1.53); //1.6
res = RoundUp(1.6); //2
或对于浮点数:
static float RoundUp(float val)
{
float a = val;
float t = a - ((int)a); //Gets only decimals
float pow = (float)Math.Pow(10, t.ToString().Length - 3);
a = a * pow; //Multiply by a power of 10 | decimal shift
a = (float)Math.Ceiling(a); //Round up
a = a / pow; //Shift back
return a;
}
var res = RoundUp(1.527f); //1.53
res = RoundUp(1.53f); //1.6
res = RoundUp(1.6f); //2
TA贡献1777条经验 获得超10个赞
var a = "1,53";
将此字符串拆分为两个,并计算小数位数:
var length = a.Split(',')[1].Length;
将原始字符串转换为双变量(替换,
为.
以避免转换过程中出现异常):
var b = Convert.ToDouble(a.Replace(',', '.'))
以指定的精度执行舍入:
var c = Math.Ceil(b, (length - 1));
并返回值替换.
为,
:
return c.ToString().Replace('.', ',');
- 4 回答
- 0 关注
- 194 浏览
添加回答
举报