none
System.Mathを省略してSinだけで使うことは出来ない? RRS feed

  • 質問

  • 外池と申します。VBで書いていた数学演算のメソッドを、C#に書き直す作業をしています。System.MathクラスのSin、Cosなどのメソッドを使うときに、メソッド名だけを書いて使うことはできないのでしょうか? あれこれ調べて、aliasを使えばSystem.Mathを最低「一文字」まで省略できることはわかったのですが・・・。

     

     

    2008年3月4日 14:31

回答

  • 残念ながら C# ではできなかったと思いますが、できないことを証明するのって難しいですね…。

    2008年3月4日 14:36
  • Code Snippet

     

    class Sample {

        public void Test(double x) {

            double value = Cos(Sin(x));

        }

        static double Sin(double a) { return Math.Sin(a); }

        static double Cos(double d) { return Math.Cos(d); }

    }

     

     

    // 異論は認めない。
    2008年3月4日 14:52

すべての返信

  • 残念ながら C# ではできなかったと思いますが、できないことを証明するのって難しいですね…。

    2008年3月4日 14:36
  • Code Snippet

     

    class Sample {

        public void Test(double x) {

            double value = Cos(Sin(x));

        }

        static double Sin(double a) { return Math.Sin(a); }

        static double Cos(double d) { return Math.Cos(d); }

    }

     

     

    // 異論は認めない。
    2008年3月4日 14:52
  • 外池です。ありがとうございました。「異論」挟まないようにします(汗)

     

    2008年3月4日 23:33
  • 書き直しとなればチェックは必要ですから、この際一発置換してしまった方が潔いような気も...

    2008年3月5日 4:59
  • System.Mathをsmと略したaliasにして、sm.Sin、sm.Logなどのように標記することにしました。

     

    ところで・・・、以下、余談ながら疑問に感じたことを、

     

    System.Mathというクラスがあって、三角関数や対数などのメソッドが用意されていて・・・、使うことには不自由しないのですが、これって、MSILにコンパイルされたときには、たぶん、クラスのメソッドを呼び出すような表現になっていると想像しています。で、実行の直前にJITコンパイルされてNativeになるときには・・・、最適な数のFPU命令で演算できるようにインラインで展開されるんでしょうねぇ?

     

    あとで、確認しようと思いますが・・・。

     

    2008年3月5日 5:18
  • 自己レスです。一応、私の環境(Windows XP、.Net Framework 2.0、C#で書いたものを混合モードでデバッグ)では、

    • 三角関数のSinは、直にIA32のFSIN命令に展開されますが、CosやTanはどこか別の場所をCALLするようです。これは、ちょっと不可解・・・。Sinを基に、自分でCosやTanの計算を書き下した方が速くなるかも・・・。
    • AbsやSqrtはIA32の命令に展開されます。
    • Log、Log10、Expは別の場所をCALLするが、これは、IA32の対数や指数の命令と底が異なり換算が必要だから、まぁ、納得できる。

    という感じでした。参考まで。

    • C#で使える手法として、正の値の場合、doubleの数値に対してFloorを使うよりは、一度intにキャストしてdoubleに戻したほうが速い。(これは、VBでは使えない。Cintで勝手な丸め操作が行われる故)

     

    2008年3月5日 8:12
  • 型を省略されるのは嫌いだけど、数学的な部分だけは可読性上がるから省略したくなりますね。

    delegate使ってもできます。どっちが早いかは知りませんが^^;

     

    Code Snippet

    delegate double TrigonometricFunction(double x);

     

    class Sample

    {

    private static readonry TrigonometricFunction Sin = Math.Sin;

    private static readonry TrigonometricFunction Cos = Math.Cos;

     

    public void Test(double x)

    {

    double val = Cos(Sin(x));

    }

    }

     

    とりあえず、delegateだとSin,Cosの中身がTest内に展開されないのだけは確実か。

     

    2008年3月5日 12:06