修正小数点后的数字

时间:2013-02-26 07:29:31

标签: c# .net

如何在十进制类型 WITHOUT ROUNDING 的点之后修复数字计数 在C#。

例如: decimal coords = 47.483749999999816; (地理坐标的一部分)

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

3 个答案:

答案 0 :(得分:6)

您可以使用

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

或者

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

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

在最后乘以0.000001m的方法往往会给出小数点后正好六位数的结果,即使有必要的尾随零也是如此。例如,coords = 1.23m会导致truncated成为1.230000m

如评论中所述,如果OverflowException过于庞大(coords超过百万分之一,则上述技术会导致 decimal.MaxValue )。

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

decimal truncated = coords - coords % 0.000001m;

这似乎工作正常。尽管尾随零的数量并不总是正确的,但我相信它会给出相同的结果。 ==运算符(或decimal.Equals)。

最后,您可以使用:

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

但仅适用于非负coords

如果您真正需要的是格式化的string,请在ToString上调用truncated重载。但是,正如我所指出的,请注意尾随零。如果使用.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)

答案 1 :(得分:0)

非常棘手,并没有建议,但我真的不知道你在寻找什么解决方案(因为你正在避免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

答案 2 :(得分:0)

您可以使用

   decimal.Round( 47.483749999999816, 6)