固定小数点后的数字计数

本文关键字:数字 字计数 小数点 | 更新日期: 2023-09-27 18:01:01

如何在不舍入的情况下修复小数类型的点后数字计数在C#中。

例如:十进制坐标=47.483749999999816;(地理坐标的一部分(

我只需要在点后保持6位数:47.483749

固定小数点后的数字计数

您可以使用

decimal truncated = Math.Truncate(coords * 1000000m) / 1000000m;

或者

decimal truncated = Math.Truncate(coords / 0.000001m) * 0.000001m;

在这两者中,我更喜欢后者。数字0.000001m在内部与小数位数6一起表示为尾数1,因此除以它实际上只是小数点移动六位。

最后乘以0.000001m的方法倾向于在小数点后正好有六位数字的结果,如果必要的话,即使后面有零。例如,coords = 1.23m将导致truncated1.230000m

如评论中所述,如果coords太大(超过decimal.MaxValue的百万分之一(,则上述技术都将导致OverflowException

为了完整起见,这里有几个其他解决方案:

decimal truncated = coords - coords % 0.000001m;

这似乎很有效。虽然尾随零的数量并不总是正确的,但我相信它给出了与==运算符(或decimal.Equals(相同的结果。

最后,您可以使用:

decimal truncated = Math.Round(coords - 0.0000005m, 6, MidpointRounding.AwayFromZero);

但这仅适用于非负CCD_ 13。

如果您真正需要的是格式化的string,请在truncated上调用ToString重载。但是,正如我所指出的,要小心尾随零。如果使用.ToString("F6"),则应该总是正好有六位小数。

当然,您也可以使用字符串操作进行截断。它会变成这样:

string coordsString = coords.ToString(CultureInfo.InvariantCulture);
int idxOfPoint = coordsString.IndexOf(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator);
if (idxOfPoint != -1 && coordsString.Length > 6 + 1 + idxOfPoint)
    coordsString = coordsString.Remove(6 + 1 + idxOfPoint);
// coordsString is now truncated correctly.
// If you need a decimal, use decimal.Parse(coordsString)

非常棘手,不建议,但我真的不知道你在寻找什么解决方案(因为你正在避免rounding(:

double k = 47.483749999999816;
k = double.Parse(Regex.Replace(k.ToString(), @"('d+'.'d{6})(.'d+)", x => x.Groups[1].Value));
Console.WriteLine(k);

打印

47.483749

您可以使用

   decimal.Round( 47.483749999999816, 6)