如何在不舍入的情况下修正十进制类型的逐点数字计数。
例如:十进制弦= 47.483749999999816;(地理坐标的一部分)
我只需要在点后停留6位数: 47.483749
发布于 2013-02-26 07:34:24
你可能会用
decimal truncated = Math.Truncate(coords * 1000000m) / 1000000m;或者也许
decimal truncated = Math.Truncate(coords / 0.000001m) * 0.000001m;在这两种情况下,我逐渐倾向于后者。数字0.000001m在内部表示为尾数1和标度6,因此除以并乘以它实际上只是小数点被6位移动。
最后用0.000001m乘积的方法往往会在小数点之后精确地给出六位数的结果,如果有必要的话,即使是尾随零。例如,coords = 1.23m将导致truncated成为1.230000m。
正如注释中所指出的,如果OverflowException太大(超过decimal.MaxValue的百万分之一),上述技术都将导致coords。
为了完整起见,以下是几个其他解决方案:
decimal truncated = coords - coords % 0.000001m;这看起来挺好的。尾随零的数目并不总是正确的,但我相信它会给出相同的结果wrt。==运算符(或decimal.Equals)。
最后,您可以使用:
decimal truncated = Math.Round(coords - 0.0000005m, 6, MidpointRounding.AwayFromZero);但这只适用于非负coords。
如果您真正需要的是格式化的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)发布于 2013-02-26 07:36:08
非常棘手,而且没有建议,但我不知道您在寻找什么解决方案(因为您正在避免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发布于 2013-02-26 07:39:51
您可以使用
decimal.Round( 47.483749999999816, 6)https://stackoverflow.com/questions/15083658
复制相似问题