none
String.Formatで四捨五入させないほう方 RRS feed

  • 質問

  • お世話になります。

    String.Fromatで桁数を指定した場合、四捨五入されず、切捨てにしたいのですが、何かいい方法はありますでしょうか
    具体的には、
    string str =  string.Format("{0:#.00}", 0.0015));
    と入れると、"0.02"が入ってしまいます。
    これを"0.01"のままにしたいのですが、かなりの場所でstring.formatを使っていて、今から日と続く切捨てを行う処理を
    入れるとなると大変で・・・
    プロジェクト全体で検索して置換とか出来る方法があれば助かります。

    すいませんが何かいい方法を知っている方、宜しくお願いいたします。
    2009年9月28日 3:45

回答

  • 簡単な置換で対応できるような簡単な問題ではないと思います。
    理由は以下のとおりです。

    まず、四捨五入ではありません。
    例えば↓は、"0.02"になります。
    string str = string.Format("{0:#.00}", 0.01499999999999999);
    また提示された例は「0.0015」から(たぶん)浮動小数点数に変換され、
    さらに、string.Format で丸められるという、なかなか複雑な例です。

    ↓参考サイト
    カスタム数値書式指定文字列
    http://msdn.microsoft.com/ja-jp/library/0c899ak8(VS.95).aspx

    切捨てを正しくおこなうには、例えば、、、
    ↓参考サイト
    指定した精度の数値に切り捨てする
    http://jeanne.wankuma.com/tips/csharp/math/rounddown.html

    以上のように、簡単な置換ではなかなか難しいかと思いますがいかがでしょうか。

    2009年9月28日 6:16
  • 0.015をMath.Floor(0.015 * 100) / 100と置換すれば可能ですが、問題はそんなに簡単じゃないですよね?

    四捨五入や偶数丸めなど、場合によってはユーザーが切り替えられるようにする必要もあります。いずれにしても端数処理は事前にきちんと確認されることをお勧めします。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年9月28日 6:41
    モデレータ
  • こんばんは。

    trapemiyaさんが書いているように
    0.015をMath.Floor(0.015 * 100) / 100
    というのを行えるようにすれば良いと思います。

    ただ、検索して置換という方法をとりたいのであれば
    string.Format() を自作メソッド ChangeFormat() に置き換えて

    private static string ChangeFormat(string format, double number)
    {
        string temp = format;

        // 前後の"{", "}"をなくす
        temp = temp.Replace("{", string.Empty);
        temp = temp.Replace("}", string.Empty); 

        // "."の位置を検索
        int position = temp.LastIndexOf(".") + 1;
        int length = temp.Length - position;

        // 掛け率を計算
        int product = 1;
        for (int i = 0; i < length; i++)
        {
            product *= 10;
        }

        return string.Format(format, Math.Floor(number * product) / product);
    }

    とすればいかがでしょうか?

    ※開発環境がこのPCにはないため、文法など間違っている場所があったらごめんなさい。
    2009年9月29日 14:35
  • こんにちわ、

    大樹さん、 Try this :

    class Program
    {
       static void Main(string[] args)
       {
          Console.WriteLine("0.0015d -> {0:N3}", (int)(0.0015d * 1000) / 1000d);
    
          float[] nums = { 0.0011f, 0.0012f, 0.0013f, 0.0014f, 0.0015f, 0.0016f, 0.0017f };
    
          foreach (float num in nums)
             Console.WriteLine("{0:n4} -> {1:N3}", num, Trunc(num, 3));
       }
    
       static double Trunc(double value, int places)
       {
          return (int)(value * Math.Pow(10, places)) / Math.Pow(10, places);
       }
    }
    antonio
    2009年9月30日 2:12

すべての返信

  • 簡単な置換で対応できるような簡単な問題ではないと思います。
    理由は以下のとおりです。

    まず、四捨五入ではありません。
    例えば↓は、"0.02"になります。
    string str = string.Format("{0:#.00}", 0.01499999999999999);
    また提示された例は「0.0015」から(たぶん)浮動小数点数に変換され、
    さらに、string.Format で丸められるという、なかなか複雑な例です。

    ↓参考サイト
    カスタム数値書式指定文字列
    http://msdn.microsoft.com/ja-jp/library/0c899ak8(VS.95).aspx

    切捨てを正しくおこなうには、例えば、、、
    ↓参考サイト
    指定した精度の数値に切り捨てする
    http://jeanne.wankuma.com/tips/csharp/math/rounddown.html

    以上のように、簡単な置換ではなかなか難しいかと思いますがいかがでしょうか。

    2009年9月28日 6:16
  • 0.015をMath.Floor(0.015 * 100) / 100と置換すれば可能ですが、問題はそんなに簡単じゃないですよね?

    四捨五入や偶数丸めなど、場合によってはユーザーが切り替えられるようにする必要もあります。いずれにしても端数処理は事前にきちんと確認されることをお勧めします。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年9月28日 6:41
    モデレータ
  • こんばんは。

    trapemiyaさんが書いているように
    0.015をMath.Floor(0.015 * 100) / 100
    というのを行えるようにすれば良いと思います。

    ただ、検索して置換という方法をとりたいのであれば
    string.Format() を自作メソッド ChangeFormat() に置き換えて

    private static string ChangeFormat(string format, double number)
    {
        string temp = format;

        // 前後の"{", "}"をなくす
        temp = temp.Replace("{", string.Empty);
        temp = temp.Replace("}", string.Empty); 

        // "."の位置を検索
        int position = temp.LastIndexOf(".") + 1;
        int length = temp.Length - position;

        // 掛け率を計算
        int product = 1;
        for (int i = 0; i < length; i++)
        {
            product *= 10;
        }

        return string.Format(format, Math.Floor(number * product) / product);
    }

    とすればいかがでしょうか?

    ※開発環境がこのPCにはないため、文法など間違っている場所があったらごめんなさい。
    2009年9月29日 14:35
  • こんにちわ、

    大樹さん、 Try this :

    class Program
    {
       static void Main(string[] args)
       {
          Console.WriteLine("0.0015d -> {0:N3}", (int)(0.0015d * 1000) / 1000d);
    
          float[] nums = { 0.0011f, 0.0012f, 0.0013f, 0.0014f, 0.0015f, 0.0016f, 0.0017f };
    
          foreach (float num in nums)
             Console.WriteLine("{0:n4} -> {1:N3}", num, Trunc(num, 3));
       }
    
       static double Trunc(double value, int places)
       {
          return (int)(value * Math.Pow(10, places)) / Math.Pow(10, places);
       }
    }
    antonio
    2009年9月30日 2:12
  • こんにちは、フォーラムオペレーターの高橋春樹です。

    あんにんごさん、trapemiyaさん、まとけんさん、Antonio H Lopesさん
    アドバイスありがとうございました。

    大樹さん、はじめまして。
    MSDNフォーラムのご利用ありがとうございます。

    皆様からアドバイスを頂いたと思うのですが、問題解決に繋がりましたか?
    今回皆様からの投稿が有用な情報だと思いましたので、
    勝手ながら、回答マークを付けさせて頂きたした。

    今後ともMSDNフォーラムをよろしくお願いします(^-^)


    マイクロソフト株式会社 フォーラム オペレーター 高橋春樹
    2009年10月13日 8:37