C#で四捨五入せずに10進数タイプのポイント後の桁数を修正するにはどうすればよいですか。
例:10進座標= 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
6
最後に掛ける方法は0.000001m
、必要に応じて末尾のゼロを含めても、小数点以下が正確に 6 桁の結果が得られる傾向があります。たとえば、にcoords = 1.23m
つながります。truncated
1.230000m
コメントで述べたように、上記の手法はどちらもOverflowException
ifcoords
が大きすぎる (の 100 万分の 1 以上decimal.MaxValue
) につながります。
完全を期すために、他のいくつかのソリューションを次に示します。
decimal truncated = coords - coords % 0.000001m;
これはうまくいくようです。ただし、末尾のゼロの数は常に正しいとは限りませんが、同じ結果が得られると思います。==
演算子 (またはdecimal.Equals
) 。
最後に、次を使用できます。
decimal truncated = Math.Round(coords - 0.0000005m, 6, MidpointRounding.AwayFromZero);
しかし、それは非負に対してのみ機能しcoords
ます。
本当に必要なものがフォーマットされた である場合は、オーバーロードをstring
呼び出します。ただし、先に示したように、末尾のゼロには注意してください。使用する場合は、常に小数点以下 6 桁にする必要があります。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)
非常にトリッキーで、提案されていませんが、どのソリューションを探しているのか本当にわかりません (回避しているため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)