AKI-H8/3052で遊ぶ ~ 簡易数値計算ライブラリ
gccのライブラリはやっぱり大きくて入りません.どこかに小さいライブラリが無いか探したのですが….っていうか,FPUの無い環境でfloatなんか使いたくありません.
ロボットの座標を計算するために,三角関数が必要だったので作ってみました.
sin,cos,tan,atan,sqrt
// sin(x) x:0~511 sin(x):-128~128 // sqrt(x) x:0~65535^2 #define sin __sin #define cos(x) sin((x)+128) #define tan(x) ((sin(x)<<7)/sin((x)+128)) #define atan __atan #define sqrt __sqrt #if defined(SIN) || defined(ATAN) //#define MAX_THETA 512 // 360deg=512 static const unsigned char sin_table[]={ 0,1,3,4,6,7,9,10,12,14,15,17,18,20,21,23, 24,26,28,29,31,32,34,35,37,38,40,41,43,44,46,47, 48,50,51,53,54,56,57,58,60,61,63,64,65,67,68,69, 71,72,73,74,76,77,78,79,81,82,83,84,85,87,88,89, 90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105, 106,107,108,108,109,110,111,112,112,113,114,115,115,116,117,117, 118,118,119,119,120,121,121,122,122,122,123,123,124,124,124,125, 125,125,126,126,126,126,127,127,127,127,127,127,127,127,127,127, 128, }; int __sin(int x) { int s=x&0x100; // sign if (x&0x80) { x=0x80-(x&0x7f); } else { x&=0x7f; } return s?-sin_table[x]:sin_table[x]; } #endif #ifdef ATAN unsigned int __atan(int x,int y) { int c=0,atan=0,s=1; long xx,yy; // +-45度に if (x+y>0) { if (x>y) { xx=x; yy=y; } else { xx=y; yy=x; atan=128; s=-1; } } else { if (x<y) { xx=-x; yy=-y; atan=256; } else { xx=-y; yy=-x; atan=384; s=-1; } } if (xx) { int i=7; int a=64,b=-64; int n; while (i--) { n=(a+b)>>1; // tan(n) >= ((yy<<7)/xx) // (sin(n)<<7)/cos(n) >= ((yy<<7)/xx) if ( xx*sin(n) >= yy*cos(n) ) { a=n; } else { b=n; } } atan+=s*a; } return atan; } #endif #ifdef SQRT unsigned int __sqrt(unsigned long d) { unsigned long a=0,t=32768; int i; for(i=0;i<16;i++) { if ((a|t)*(a|t)<=d) { a|=t; } t>>=1; } return a; } #endif
使い方
必用な機能をdefineして有効にしてください.
sinの周期は512,振幅は128です.sinはテーブルから作ってます.cos,tanは単なるマクロです.atanはatan2です.
終わりに
sinテーブルはPerlで作りましたが,こういうのが自動で出来る強力なプリプロセッサが欲しいと思うのは私だけですか?むしろ,C言語で書けるプリプロセッサ…というか,コンパイル時に計算するべき処理を指定できるプログラミング言語が欲しいような….
この文書の履歴
- 2006-03-26 公開
Copyright © binzume all rights reserved.