はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【C#】浮動小数点をToString()するとCultureInfoによって出力が異なってしまう件

はじめに

1.23f.ToString()のような浮動小数点のToStringを実行するとカルチャ(国/地域)によって表示が異なることに最近気がつきました。

// ja-JP
Console.WriteLine(CultureInfo.CurrentCulture);
            
// 1.23
Console.WriteLine(1.23f.ToString(CultureInfo.CurrentCulture));

// 1.23
Console.WriteLine(1.23f.ToString(new CultureInfo("en-US")));
            
// 1,23
// 「.」ではなく「,」が利用されている
Console.WriteLine(1.23f.ToString(new CultureInfo("fr-FR")));

この現象について軽く調べたのでその備忘録を残しておきたいと思います。

概要

前述の通り、.NETではToStringカルチャ依存になっています。

数値、日時など、文字列以外のデータをユーザーに表示するには、ユーザーのカルチャ設定を使用して書式設定します。 既定では、以下のすべてで、書式設定操作での現在のカルチャが使用されます。

  • C# と Visual Basic のコンパイラでサポートされている挿入文字列。
  • C# または Visual Basic の連結演算子を使用または String.Concat メソッドを直接呼び出す文字列連結操作。
  • String.Format メソッド。
  • 数値型と日時型の ToString メソッド。

.NET での書式付きデータの表示と保持に関するベスト プラクティス - .NET | Microsoft Learn

ちなみに設定されているカルチャはCultureInfo.CurrentCultureプロパティから取得することができます。

// ja-JP
Console.WriteLine(CultureInfo.CurrentCulture);

CultureInfo.CurrentCulture プロパティ (System.Globalization) | Microsoft Learn

対処法

カルチャに依存しないようにするにはCultureInfo.InvariantCultureを利用してあげれば良いようです。

インバリアント カルチャはカルチャに依存しません。これは英語に関連付けられていますが、国/地域には関連付けされません。
...
ユーザーのカスタマイズや、.NET Frameworkやオペレーティング システムの更新によって変更されるカルチャに依存するデータとは異なり、インバリアント カルチャ データは時間の経過と共に、インストールされているカルチャ間で安定しており、ユーザーがカスタマイズすることはできません。 これにより、インバリアント カルチャは、書式設定されたデータを保持する書式設定および解析操作や、カルチャに関係なく固定された順序でデータを表示する必要がある並べ替えと順序付け操作など、カルチャに依存しない結果を必要とする操作に特に役立ちます。

public static System.Globalization.CultureInfo InvariantCulture { get; }

CultureInfo.InvariantCulture プロパティ (System.Globalization) | Microsoft Learn

// 1.23
Console.WriteLine(1.23f.ToString(CultureInfo.InvariantCulture));

カルチャ依存によって起こった時事ネタ

indiegamesjp.dev