sin関数の計算結果がGR-SAKURAと違う?

ド素人ですw。以前にGR-SAKURAのフォーラムで「8×8×8のLED-CUBEを作ったけど、うまく動かない」で助けて頂いた者です。

https://japan.renesasrulz.com/gr_user_forum_japanese/f/gr-sakura/3717/thread

同じLED-CUBEをとある事情で、SAKURA->秋月で買ったRX621ボードへの移植をしてます。(せっかくかわいいSAKURAボードは、他の用事に使おうかとw)

e2studioで作ってます。なんとかほぼ動くようになったのですが、sinを使ってる所でSAKURAとLEDの表示が違います…。

SAKURAの方のプログラムの該当部分は、

1 :  void ripples(int times, int repeat)
2 :  {
3 :    int i,j,k,z;
4 :    float distance,ztemp;
5 :    clearData();

6 :    for(k=0;k<=repeat;++k) {
7 :      for(i=0;i<=3;++i) {
8 :        for(j=0;j<=3;++j) {
9 :          distance=sqrt((3.5-(float)i)*(3.5-(float)i)+(3.5-(float)j)*(3.5-(float)j));
10:          ztemp=3.5+sin(distance/1.3+(float)k/3.14159)*3.5;
11:          z=(int)(ztemp+0.5);
12:          bitSet(dispData[z][i],j);
13:          bitSet(dispData[z][7-i],j);
14:          bitSet(dispData[z][i],7-j);
15:          bitSet(dispData[z][7-i],7-j);
16:        }
17:      }
18:      LEDDisp(times);
19:      clearData();
20:    }
21:  }

LED表示用配列の辺は見ないで頂いて(移植に伴いbitsetー>ビットシフトに変えてます)、9~11行目の式で、がじぇるねのwebコンパイラでビルドしたSAKURAと、e2studioでビルドしたRX621ボードとで、計算結果が異なる原因が何かあるでしょうか…?

sqrtとsinをsqrtfとsinfに変えてみたりとか、型指定を外してみたりとかしても、変わらない様です。

(printfで計算結果を確認しようとしたのですがうまくいかないので、ほんとに計算結果が違うかどうかは確認できていません…)

どなたかご助言頂けると助かります。

Parents
  • sin や sqrt 等数学関数は math.h をインクルードしないと正常動作しませんがされてますか
  • もちろん、エラーが出ずにビルド・書き込み・実物実行してるので、インクルードしてます。
    (今見たら…、sin・sqrtとsinf・sqrtfと、どちらを使うべきなのか分からないので、math.hとmathf.hと両方インクルードしてたつもりだったのですが、LibraryGeneratorの「構成」の画面(先ほどのrepに張り付けてる)でmathf.hにチェック入れてるけど、インクルードはmath.hしか記述してませんでした。)
  • > もちろん、エラーが出ずにビルド・書き込み・実物実行してるので、

    関数プロトタイプが含まれるヘッダファイルのインクルードを忘れてもエラーとはならずに警告が出るだけだと思いますが一つの警告も出ていないでしょうか?
  • インクルードはしてるつもりなのですが…。警告は「W0561017:The evaluation period has expired」というのが1つ出てるようですが…。
Reply Children
  • > 警告は「W0561017:The evaluation period has expired」というのが1つ

    「お試し期間終わったから金払え」ということですがとりあえず無視して良いです。
  • あ、そのヤツか~ww。プログラムのサイズ制限があるんだったかしら?(辞書引いても分からなかったw)
    ありがとです~。(「変数やユーザー定義関数の評価をせー」とかいう意味かと思ったw。)
  • がじぇるね岡宮です。

    #すみません、コードの中で、for文のkの演算が足りてないですね。つねに0で計算しているため、不十分です。

    CCRXと、Webコンパイラで使っているGCCで違いが出るか、GR-SAKURAで試してみましたが、結果としては一緒でした。

    for文2個で4回ずつ計16回ループしているため、かなり限定的な演算の比較なので、どれくらいsinの結果が一致してるかは未検証です。できれば、どういった差分が出るのか教えていただけるとありがたいです。

     

    ■Renesas CCRX V3.02.00

    (新規プロジェクト作成で、FITモジュールのbspのみ適用、LibGenでmath.hを追加)

    コード

    #include <stdio.h>
    #include <math.h>
    void main(void)
    {
    int i,j,k,z;
    float distance,ztemp;
    for(i=0;i<=3;++i) {
    for(j=0;j<=3;++j) {
    distance=sqrt((3.5-(float)i)*(3.5-(float)i)+(3.5-(float)j)*(3.5-(float)j));
    ztemp=3.5+sin(distance/1.3+(float)k/3.14159)*3.5;
    z=(int)(ztemp+0.5);
    printf("%d",z);printf(",");printf("%d",i);printf(",");printf("%d",j);
    printf("\r\n");
    printf("%d",z);printf(",");printf("%d",7-i);printf(",");printf("%d",j);
    printf("\r\n");
    printf("%d",z);printf(",");printf("%d",i);printf(",");printf("%d",7-j);
    printf("\r\n");
    printf("%d",z);printf(",");printf("%d",7-i);printf(",");printf("%d",7-j);
    printf("\r\n");
    printf("\r\n");
    }
    }
    while(1) {

    // TODO: add application code here
    }

    }

    結果

    1,0,0
    1,7,0
    1,0,7
    1,7,7

    3,0,1
    3,7,1
    3,0,6
    3,7,6

    4,0,2
    4,7,2
    4,0,5
    4,7,5

    5,0,3
    5,7,3
    5,0,4
    5,7,4

    3,1,0
    3,6,0
    3,1,7
    3,6,7

    5,1,1
    5,6,1
    5,1,6
    5,6,6

    6,1,2
    6,6,2
    6,1,5
    6,6,5

    7,1,3
    7,6,3
    7,1,4
    7,6,4

    4,2,0
    4,5,0
    4,2,7
    4,5,7

    6,2,1
    6,5,1
    6,2,6
    6,5,6

    7,2,2
    7,5,2
    7,2,5
    7,5,5

    7,2,3
    7,5,3
    7,2,4
    7,5,4

    5,3,0
    5,4,0
    5,3,7
    5,4,7

    7,3,1
    7,4,1
    7,3,6
    7,4,6

    7,3,2
    7,4,2
    7,3,5
    7,4,5

    5,3,3
    5,4,3
    5,3,4
    5,4,4

     

    ■Webコンパイラ(KPIT GNURX-ELF Toolchain 14.03.. ちょっと古くて恐縮ですが、Mac版IDE for GRと合わせるためバージョン変更してません)

    (mathはNewlib prebuild使用)

    コード

    void setup()
    {
    Serial.begin(9600);
    delay(1000);
    int i,j,k,z;
    float distance,ztemp;
    for(i=0;i<=3;++i) {
    for(j=0;j<=3;++j) {
    distance=sqrt((3.5-(float)i)*(3.5-(float)i)+(3.5-(float)j)*(3.5-(float)j));
    ztemp=3.5+sin(distance/1.3+(float)k/3.14159)*3.5;
    z=(int)(ztemp+0.5);
    Serial.print(z);Serial.print(",");Serial.print(i);Serial.print(",");Serial.print(j);
    Serial.println();
    Serial.print(z);Serial.print(",");Serial.print(7-i);Serial.print(",");Serial.print(j);
    Serial.println();
    Serial.print(z);Serial.print(",");Serial.print(i);Serial.print(",");Serial.print(7-j);
    Serial.println();
    Serial.print(z);Serial.print(",");Serial.print(7-i);Serial.print(",");Serial.print(7-j);
    Serial.println();
    Serial.println();
    delay(100);
    }
    }

    }

    void loop(){
    }

     

    結果

    1,0,0
    1,7,0
    1,0,7
    1,7,7

    3,0,1
    3,7,1
    3,0,6
    3,7,6

    4,0,2
    4,7,2
    4,0,5
    4,7,5

    5,0,3
    5,7,3
    5,0,4
    5,7,4

    3,1,0
    3,6,0
    3,1,7
    3,6,7

    5,1,1
    5,6,1
    5,1,6
    5,6,6

    6,1,2
    6,6,2
    6,1,5
    6,6,5

    7,1,3
    7,6,3
    7,1,4
    7,6,4

    4,2,0
    4,5,0
    4,2,7
    4,5,7

    6,2,1
    6,5,1
    6,2,6
    6,5,6

    7,2,2
    7,5,2
    7,2,5
    7,5,5

    7,2,3
    7,5,3
    7,2,4
    7,5,4

    5,3,0
    5,4,0
    5,3,7
    5,4,7

    7,3,1
    7,4,1
    7,3,6
    7,4,6

    7,3,2
    7,4,2
    7,3,5
    7,4,5

    5,3,3
    5,4,3
    5,3,4
    5,4,4

  • がじぇるね岡宮です。

    試しにk=3として、同じ演算をしてみましたが、結果としては同じでした。RX621は持っていないため、やれてません。あまり解決の糸口にならずすみませんが、とりあえずの実験結果でした。

    CCRX GCC

    0,0,0
    0,7,0
    0,0,7
    0,7,7

    0,0,1
    0,7,1
    0,0,6
    0,7,6

    1,0,2
    1,7,2
    1,0,5
    1,7,5

    2,0,3
    2,7,3
    2,0,4
    2,7,4

    0,1,0
    0,6,0
    0,1,7
    0,6,7

    2,1,1
    2,6,1
    2,1,6
    2,6,6

    3,1,2
    3,6,2
    3,1,5
    3,6,5

    4,1,3
    4,6,3
    4,1,4
    4,6,4

    1,2,0
    1,5,0
    1,2,7
    1,5,7

    3,2,1
    3,5,1
    3,2,6
    3,5,6

    5,2,2
    5,5,2
    5,2,5
    5,5,5

    6,2,3
    6,5,3
    6,2,4
    6,5,4

    2,3,0
    2,4,0
    2,3,7
    2,4,7

    4,3,1
    4,4,1
    4,3,6
    4,4,6

    6,3,2
    6,4,2
    6,3,5
    6,4,5

    7,3,3
    7,4,3
    7,3,4
    7,4,4

    0,0,0
    0,7,0
    0,0,7
    0,7,7

    0,0,1
    0,7,1
    0,0,6
    0,7,6

    1,0,2
    1,7,2
    1,0,5
    1,7,5

    2,0,3
    2,7,3
    2,0,4
    2,7,4

    0,1,0
    0,6,0
    0,1,7
    0,6,7

    2,1,1
    2,6,1
    2,1,6
    2,6,6

    3,1,2
    3,6,2
    3,1,5
    3,6,5

    4,1,3
    4,6,3
    4,1,4
    4,6,4

    1,2,0
    1,5,0
    1,2,7
    1,5,7

    3,2,1
    3,5,1
    3,2,6
    3,5,6

    5,2,2
    5,5,2
    5,2,5
    5,5,5

    6,2,3
    6,5,3
    6,2,4
    6,5,4

    2,3,0
    2,4,0
    2,3,7
    2,4,7

    4,3,1
    4,4,1
    4,3,6
    4,4,6

    6,3,2
    6,4,2
    6,3,5
    6,4,5

    7,3,3
    7,4,3
    7,3,4
    7,4,4

  • 皆様回答・検証ありがとうございます。さて今のところ「そんなはずはない」という結果で、「ほんとに同じ式入れた?」と自信がなくなってきました…。
    夕べ遅くまで出掛けててもうひと眠りしたいのですが、ちょっと確認します…。(いろいろバタバタ試行錯誤しながらやってるので、式間違えてたら超人騒がせになってしまう…)
  • 確認したのですが、式は間違えて無さそう…

    動画撮ったのですが、サイズが大きすぎて張り付けられないので、しばしお待ちください…。

    SAKURAはピンケーブルでLED基板側に繋いでたのですが、接触が悪く不確実で、今回何か専用のボードを買ってハンダ付けで配線しようと思ったのが、SAKURAー>RX621に変更した理由の一つです。

    ハンダ付けで結線したRX621ボードを外すのは大変なので、RX621は繋いだまま、残してたピンソケットに無理やりSAKURAも繋いで動作確認しました。

    SAKURA側はwebコンパイラでビルド仕直して、書き込みしなおしてます。今まで通りのLED表示でした。ちなみに「repeat」は名前の通り、何回繰り返すかで、メインループからrepeat=150で呼び出しています。

    この式をe2studioの方にそのままコピペして、再ビルド・再書き込み。やはりおかしなLED表示でした…。

    (下のコメントアウトは、「ほ~ら式が間違ってたんじゃん?」の検証のために、昨日までの状態を残しておいたもの。上の式3行が、webコンパイラーからそのままコピペした物。う~ん、そのままコピペだし式に相違はないはず…)

    動画のファイルサイズ縮小ができたら、動画載せます。今回のLED-CUBEの全体は、ぼくのブログを参照下さい。

    https://blog.goo.ne.jp/kohei-m/e/c66bda3027eae9e72a22d286a561bdf9

  • 動画縮小・変換できました、張り付けてみます。「動画で言うな、数字で言え!」と怒られそうですけど…w

    まず、SAKURAで動かしたときの動画です。

     

    (必要ない所がちょっとピカピカしてる様ですが、信号線が不安定か、RX621を繋ぎっぱなしにしてる影響かも。無視して下さい。)

  • 次が「おかしいんじゃない?」というRX621で動かしたときの動画です。

     

    それっぽい動きですが、明らかにSAKURAの時と違います…。sinを使った表示は他にも、RX621の方の動画の中ほどに、波みたいなヤツがありますが、それはSAKURAと変わらないように思えます。(という事は、sinの方の式じゃなくて、distance=sqrt…の方の計算結果が違うのかしら…)

  • RX621の方をスローにした動画です。(関数呼び出しの際に、timesを大きくすれば遅くなる作りです。)

     

    LED表示は、一番上がz=0、一番下がz=7のはずです。この動画からzがいくつになってるかを拾うのは…厳しそうですが、ちょっと考えてみます。

  • 元々この式は、LED-CUBEを作った人のどっか外国のサイトから取った式ですが、1つのkに対してLED表示データセット一式を作るのに、sqrtとsinの計算を8×8=64回もするので、さすがのSAKURAでも動きがギクシャクしました。
    よく考える(見る)と、中心から各4隅まで対称なので「計算4分の1にできるじゃん」と、計算を4×4=16回に減らして、同じzで4カ所のLEDを点灯に設定してます。
    (i=0~7、j=0~7を、i=0~3、j=0~3に減らした上で、8×8のデータ全部を埋める。)