x 過去ログをみよ
目的
割り算を高速化する
UNOからのアナログ入力を自動で絞りたい
いろいろ
割り算の為の前処理が重すぎる
範囲エラーは、テーブルから余計なアドレスにアクセスさせない為
y/1とy/2は、内部の掛け算でオーバーフローをさせない為
仕様
①範囲エラー処理と割られる数0、割る数0は、0
②例外処理と高速化の為 x/1は、xは、そのまま
③範囲エラーを防ぐ為と高速化の為にx/2は1シフト
④1/yのメイン処理 例 64/4=16 64*64/256=16
⑤あと、符号処理
⑥割られる数は、チェックは、しない。だいたい300ぐらいまでOK
結果
プログラム
// 1/xのテーブルを使った8ビット単位の割り算 正の数、負の数
//DIV_C_UNO1
// 8ビット / 8ビット の 正の数、負の数の割り算
int DIV_C(int x, int y) {
static unsigned char uu[] = {
255, 255, 128, 85, 64, 51, 42, 36,
32, 28, 25, 23, 21, 19, 18, 17,
16, 15, 14, 13, 12, 12, 11, 11,
10, 10, 9, 9, 9, 8, 8, 8,
8, 7, 7, 7, 7, 6, 6, 6,
6, 6, 6, 5, 5, 5, 5, 5,
5, 5, 5, 5, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
2, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1
, 1
};
//範囲エラー処理と割られる数0、割る数0
if ( y > 256 ) {return (0);}
if ( y < -256 ) {return (0);}
if ( y == 0 ) {return (0);}
if ( x == 0 ) {return (0);}
//結果の符号を保存、符号を外す
int p;
p = x ^ y;
p = (p >> 15);
//c = (c ^ p) - p;
if(x < 0) {x--;x =~ x;}
if(y < 0) {y--;y =~ y;}
//例外処理と高速化の為 x/1は、xは、そのまま
if ( y == 1 ) { return ((x^p)-p);}
//範囲エラーを防ぐ為と高速化の為にx/2は1シフト
if ( y == 2 ) {return (((x >> 1)^p)-p);}
// 1/yのメイン処理 例 64/4=16 64*64/256=16
return ((((x * uu[y]) >> 8)^p)-p) ;
}//DIV_C
//初期化
void setup() {
// put your setup code here, to run once:
//シリアルポートの初期化
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}//setup
//メインループ
void loop() {
// put your main code here, to run repeatedly:
/*
Serial.println("debug");
//範囲エラー、負の数のテスト
Serial.print("257/2="); Serial.println(DIV_C(257, 2));
Serial.print("128/257="); Serial.println(DIV_C(128, 257));
Serial.print("-10/2="); Serial.println(DIV_C((-10), 2));
Serial.print("128/-10="); Serial.println(DIV_C(128, (-10)));
// n/1とn/0のテスト
Serial.print("128/1="); Serial.println(DIV_C(128, 1));
Serial.print("128/0="); Serial.println(DIV_C(128, 0));
Serial.print("256/1="); Serial.println(DIV_C(256, 1));
Serial.print("256/0="); Serial.println(DIV_C(256, 0));
// n/2のテスト
Serial.print("128/2="); Serial.println(DIV_C(128, 2));
*/
//通常ケース
Serial.print("64/4="); Serial.println(DIV_C(64, 4));
//3秒待つ
delay(3000);
}//loop