2007年10月8日月曜日

論理積と論理和と排他的論理和で足し算する

ビット演算で足し算を行うスクリプト。
単純で短いスクリプトですが、再帰が必要だったり排他的論理和(XOR)演算を行う必要があったりと少々高度です。やっていることは小学校で習う「筆算」と同じなのですが。

CPU内部の演算は、もしかしたらこうして行われているのかもしれませんね。ちょっと調べてみます。
#module
#defcfunc add int left_op, int right_op
    kuri = ( left_op & right_op ) << 1  // 繰り上がり
    if ( kuri == 0 ) {
        // 繰り上がりがなければ論理和を返す
        return ( left_op | right_op )
    } else {
        // 繰り上がりがある場合は、
        // 繰り上がりと排他的論理和の結果を加算する
        return add( left_op ^ right_op, kuri )
    }
#global
    randomize
    repeat 10
        l = rnd99 ) + 1
        r = rnd99 ) + 1
        mes strf"%2d", l ) + " + " + strf"%2d", r ) + " = " + strf"%3d"add( l, r ) )
    loop
    stop

再帰ではなくループを使う方法はこちら。

#module
#defcfunc add int left_op, int right_op
    left = left_op : right = right_op
    while ( left & right )
        tmp = ( left & right ) << 1
        left ^= right
        right = tmp
    wend
    return ( left | right )
#global
    randomize
    repeat 10
        l = rnd99 ) + 1
        r = rnd99 ) + 1
        mes strf"%2d", l ) + " + " + strf"%2d", r ) + " = " + strf"%3d"add( l, r ) )
    loop
    stop

0 件のコメント: