如何在十进制类型 WITHOUT ROUNDING 的点之后修复数字计数 在C#。
例如: decimal coords = 47.483749999999816; (地理坐标的一部分)
我需要在点之后只保留6位数:47.483749
答案 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)