C言語でべき乗表現

こんにちは、NAKAといいます。

C言語基礎を確認させてください。

pow()っていう関数を使うと思うのですが

例えば2^15って0x8000だと思うのですが、実際やってみると0x7FFFになってしまいます。

  • NAKAさん、こんにちは。Sugachanceです。

    NAKAさんの場合、RL78なのかRXなのかRH850なのかはたまた他のやつなのか…
    分かりませんが、手元のRL78の環境の場合仰るように0x7FFFになりました(intに渡した時)。

    pow()関数自体、引数も戻値もdouble型ですが、
    RL78の環境だとdoubleはfloatと同じ4バイト(だった気がするので)
    そのあたりの精度・切り捨てとキャストの兼ね合いな気がします。

    double ans;
    int ansi;
    ans = pow(2,15);
    ansi= pow(2,15);

    の結果をウォッチで見てみたら
    ans 3.276798E+004 float(4)
    ansi 32767 (0x7fff) int(2)

    ってなってました。

    先日、Cに関して素人レベルだと怒られてしまったので
    プロレベルの詳しい方の解説が欲しいところです!

  • doubleのオプションを付けたら
    ans 3.276800000000004E+004 double(8)
    ansi -32768 (0x8000) int(2)
    になりました!

  • Sugachanceさん お久しぶりです。
    ナカです。いつもありがとうございます。
    僕も、基礎がないのですぐつまずいちゃいます。

    じつは先日までpow関数も知らずに A=2^15;とか書いちゃって
    「おかしいなあ計算結果が全然ちがう!」とかやってました(*_*)
    ビルドでエラーが出ないと正しいと思いこんじゃいますね。

  • NAKAさん、Sugachanceさん、こんにちは。NoMaYです。

    他の言語のべき乗2項演算子とC言語のべき乗数学関数の違いが認識出来ていないのかなぁ、と思いました。

    Fortran (参考 www.ile.osaka-u.ac.jp/research/cmp/download/fortran90-text-v4.pdf#page=10)

     x ** y

    R (参考 ds.k.kyoto-u.ac.jp/wp-content/uploads/2021/10/slide-a02.pdf#page=15)

     x ^ y

    いろいろまとめ

    hydrocul.github.io/wiki/programming_languages_diff/number/pow.html

    こぼればなし

    blog.media.teu.ac.jp/2021/08/post-89817a.html

    数学関数としてのべき乗としては、ググってみたのですが、以下のウェブページを参照してみてはどうかな、と思いました。(CC-RLライブラリでの計算方法はともかくとして、浮動小数点計算をするものである、単純に x を y 回だけ掛け算するものでは無い、というイメージとしてです。)

    hiroyukichishiro.com/power-and-exponentiation-in-c-language/

    自作関数でべき乗の計算


  • NAKAさん、こんにちは

    RL78とすれば、
    「CC-RL コンパイラ ユーザーズマニュアル」あたりから確認するものではないでしょうか。

    手元の Rev.1.11 (2021.11) 「4. コンパイラ言語仕様」を見ると、int は、2バイトで、先頭1bitが符号ビットなので、
    正数の最大値は、0x7FFF(32767) となり、多分、丸めでしょう。
    double → intの丸めが見つからならなかったのですが、正数の最大値かな、と。

    この辺は、C言語というより、実装依存かな、と思う次第です。

  • NoMaYさん、 KatoNaganoさん、Sugachanceさん
    皆さんありがとうございます。NAKAです。

    元々、MicrochipのSAM71V(intは32bit)での疑問で、RL78で確認してもおかしかったので、
    お聞き致しました。

    元々、回路のハード設計出身でソフトは見様見真似でしっかり
    勉強してないことを反省してます。

    こういう場があるのは本当に助かります。

    どうも最近ルネサスのエディタの調子が?です。

    アルファベット打ってもカタカナになるし、ヘンテコに入力されるし...?((+_+))

  • NAKAさん、こんにちは。NoMaYです。

    それで、どういうことだったのかというのは理解出来た、ですかね?

  • NoMaYさん、NAKAです。

    数学的本質みたいなのは理解できてませんが、教えていただいたページは興味深く見させて頂きました。
    0.5乗はルートだし、そもそも^はEXORですものね!

    VBでは^がべき乗みたいですが、今更なにを!って感じですかね!

    ちょっと前まで、switch~caseをselect~caseって打って怒られてました (*_*;

    諸悪の原因はEXCELかな?


  • マニュアルを見ると、pow関数は、double を引数にとって、doubleを返します。

    戻り値をintに代入しているので、double → intの変換が入ります。

    なお、intは、C言語の規則としては、 short ≦ int ≦ long となっていて、16bit CPU以下では、16bitが多く、 32bit以上では、32bitが多いようですが、処理系依存。

    あと、RL78だと、レジスタが16bitまでしかないので、double(64bit) 以前に float(32bit)も使いたくない、、というなのが、個人的な気持ち。

  • Sugachanceさん NAKAです。


    >doubleのオプションを付けたら
    ⇒ってどこのオプションでしたっけ?
    プロパティのコンパイラ・オプションくらいかなと早合点してました。

    やっぱり、なんか変です。

    pow(2,2)=0x3になっちゃうし

    mathfをインクルードたら更におかしなことになりました。

    RL78でもRH850でも同じ感じでした。


    0.5乗は上手くいく!

    やっぱり、変