加入收藏 | 设为首页 | 会员中心 | 我要投稿 银川站长网 (https://www.0951zz.com/)- 云通信、基础存储、云上网络、机器学习、视觉智能!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

JavaScript达成串行加法器的代码是什么

发布时间:2023-08-03 12:48:22 所属栏目:语言 来源:
导读:这篇文章给大家分享的是“JavaScript实现串行加法器的代码是什么”,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下吧。测试断言工具TestUtils.jsfuncti

这篇文章给大家分享的是“JavaScript实现串行加法器的代码是什么”,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下吧。

测试断言工具TestUtils.js

function assertTrue(actual){

    if(!actual)

        throw "Error actual: " + actual + " is not true."

}

function assertFalse(actual){

    if(actual)

        throw "Error actual: " + actual + " is not false."

}

function assertIntEquals(expected, actual){

    if(typeof expected != "number")

        throw "Error expected: " + expected +" is not a number."

    if(typeof actual != "number")

        throw "Error actual: " + actual +" is not a number."

    if(expected != actual)

        throw "Error expected: " + expected + " and actual: " + actual +" is different."

}

十进制数与二进制数之间转换工具utils.js

function int2LowEightBitArray(num){

    var result = []

    for(var i = 0; i < 8; i++)

        result.push(((num >> i) & 1) == 1)

    return result

}

function lowEightBitArray2Int(array){

    var result = 0

    for(var i = 0; i < 8; i++){

        if(array[i])

            result += (1 << i)

    }

    return result

}

function lowNineBitArray2Int(array){

    var result = 0

    for(var i = 0; i < 9; i++){

        if(array[i])

            result += (1 << i)

    }

    return result

}

//用补码表示负数

function int2EightBitArray(num){

    if(num < -128 || num > 127){

        throw "Out of boundary(-128, 127)."

    }

    var result = []

    for(var i = 0; i < 8; i++)

        result.push(((num >> i) & 1) == 1)

    return result

}

function eightBitArray2Int(array){

    var result = 0

    for(var i = 0; i < 7; i++){

        if(array[i])

            result += (1 << i)

    }

    if(array[i])

        result += -128

    return result

}

function int2SixteenBitArray(num){

    if(num < -(1 << 15) || num > (1 << 15) - 1){

        throw "Out of boundary({left}, {right})."

            .replace("{left}", -(1 << 15))

            .replace("{right}", (1 << 15) - 1)

    }

    var result = []

    for(var i = 0; i < 16; i++)

        result.push(((num >> i) & 1) == 1)

    return result

}

function sixteentBitArray2Int(array){

    var result = 0

    for(var i = 0; i < 15; i++){

        if(array[i])

            result += (1 << i)

    }

    if(array[i])

        result += -(1 << 15)

    return result

}

加法器模型model.js

class DoubleInGate{

    #id

    #in1

    #in2

    #gateTypeName

    #func

    #out

    #lastOut

    #outReceiver

    #outReceiverInName

    constructor(id, gateTypeName, in1 = false, in2 = false, func){

        this.#id = id

        this.#gateTypeName = gateTypeName

        this.#in1 = in1

        this.#in2 = in2

        this.#func = func

        this.#out = this.#func(this.in1, this.in2)

        // this.#lastOut = this.#out

    }

    updateIn1(flag){

        this.#in1 = flag

        this.#updateOut()

    }

    updateIn2(flag){

        this.#in2 = flag

        this.#updateOut()

    }

    getOut(){

        return this.#out;

   }

    updateBothIn(in1 = false, in2 = false){

        this.#in1 = in1

        this.#in2 = in2

        this.#updateOut()

    }

    setOutReceiver(outReceiver, inName){

        this.#outReceiver = outReceiver

        this.#outReceiverInName = inName

    }

    #updateOut(){

        this.#lastOut = this.#out

        this.#out = this.#func(this.#in1, this.#in2)

        if(this.#out != this.#lastOut){

            this.#send(this.#out)

        }

    }

    #send(flag){

        if(this.#outReceiver){

            this.#outReceiver.receive(this.#outReceiverInName, flag)

        }

    }

    receive(inName, flag){

        if(inName == "in1"){

            this.updateIn1(flag)

        }else if(inName == "in2"){

            this.updateIn2(flag)

        }

    }

    toString(){

        return "{gateTypeName} id: {id}, in1: {in1}, in2: {in2}, out:{out}"

            .replace("{gateTypeName}", this.#gateTypeName)

            .replace("{id}", this.#id)

            .replace("{in1}", this.#in1)

            .replace("{in2}", this.#in2)

            .replace("{out}", this.#out)

    }

}

//与门

class AndGate extends DoubleInGate{

    constructor(id, in1 = false, in2 = false){

        super(id, "AndGate", in1, in2, (i1, i2) => i1 && i2)

    }

}

//或门

class OrGate extends DoubleInGate{

    constructor(id, in1 = false, in2 = false){

        super(id, "OrGate", in1, in2, (i1, i2) => i1 || i2)

    }

}

//异或门

class XorGate extends DoubleInGate{

    constructor(id, in1 = false, in2 = false){

        //^在js按位异或, 而在java中不是

        super(id, "XorGate", in1, in2, (i1, i2) => (i1 || i2) && !(i1 && i2)) 

    }

}

class SingleInGate{

    #id

    #in

    #out

    #lastOut

    #func

    #outReceiver

    #outReceiverInName

    constructor(id, in_, func){

        this.#id = id

        this.#in = in_

        this.#func = func

        this.#out = this.#func(this.#in)

        // this.#lastOut = this.#out

    }

    updateIn(flag){

        this.#in = flag

        this.#updateOut()

    }

    getOut(){

        return this.#out

    }

    //注册输出端口接收者,(类观察者模式)

    setOutReceiver(outReceiver, inName){

        this.#outReceiver = outReceiver

        this.#outReceiverInName = inName

    }

    #updateOut(){

        this.#lastOut = this.#out

        this.#out = this.#func(this.#in)

        if(this.#out != this.#lastOut){

            this.#send(this.#out)

        }

    }

    #send(flag){

        if(this.#outReceiver){

            this.#outReceiver.receive(this.#outReceiverInName, flag)

        }    

    }

    receive(inName, flag){

        if(inName == "in"){ //TODO 或许有更灵活的写法

            this.updateIn(flag)

        }

    }

}

class NullGate extends SingleInGate{

    constructor(id, in_= false){

        super(id, in_, a=>a)

    }

}

class NotGate extends SingleInGate{

    constructor(id, in_= false){

        super(id, in_, a=>!a)

    }

}

class Adder{

    #id

    #inA

    #inB

    #outS

    #outC

    #lastOutS

    #lastOutC

    #outSReceiver

    #outSReceiverInName

    #outCReceiver

    #outCReceiverInName

    constructor(id, inA=false, inB=false, outS, outC){

        this.#id = id

        this.#inA = inA

        this.#inB = inB

        this.#outS = outS

        this.#outC = outC

    }

    updateInA(flag, func){

        this.#inA = flag

        this.updateOutSAndOutC(func)

    }

    updateInB(flag, func){

        this.#inB = flag

        this.updateOutSAndOutC(func)

    }

    updateBothIn(inA, inB, func){

        this.#inA = inA

        this.#inB = inB

        this.updateOutSAndOutC(func)

    }

    getOutS(){

        return this.#outS

    }

    getOutC(){

        return this.#outC

    }

    #updateOutS(flag){

        this.#lastOutS = this.#outS

        this.#outS = flag

        if(this.#outS != this.#lastOutS){

            this.#sendOutS(this.#outS)

        }

    }

    #updateOutC(flag){

        this.#lastOutC = this.#outC

        this.#outC = flag

        if(this.#outC != this.#lastOutC){

            this.#sendOutC(this.#outC)

        }

    }

    updateOutSAndOutC(func){

        if(func){

            var results = func()

            this.#updateOutS(results[0])

            this.#updateOutC(results[1])

        }

    }

    setOutSReceiver(outSReceiver, inName){

        this.#outSReceiver = outSReceiver

        this.#outSReceiverInName = inName

    }

    setOutCReceiver(outCReceiver, inName){

        this.#outCReceiver = outCReceiver

        this.#outCReceiverInName = inName

    }

    receive(inName, flag){

        if(inName == "inA"){

            this.updateInA(flag)

        }else if(inName == "inB"){

            this.updateInB(flag)

        }

    }

    #sendOutS(flag){

        if(this.#outSReceiver){

            this.#outSReceiver.receive(this.#outSReceiverInName, flag)

        }

    }

    #sendOutC(flag){

        if(this.#outCReceiver){

            this.#outCReceiver.receive(this.#outCReceiverInName, flag)

        }

    }

}

class HalfAdder extends Adder{

    #xorGate

    #andGate

    constructor(id, inA=false, inB=false){

        var xorGate = new XorGate(undefined, inA, inB);

        var andGate = new AndGate(undefined, inA, inB);

        super(id, inA, inB, xorGate.getOut(), andGate.getOut())

        this.#xorGate = xorGate

        this.#andGate = andGate 

    }

    #returnOutArray(){

        return [this.#xorGate.getOut(), this.#andGate.getOut()]

    }

    updateInA(flag){

        super.updateInA(flag, ()=>{

            this.#xorGate.updateIn1(flag)

            this.#andGate.updateIn1(flag)

            return this.#returnOutArray()

        })

    }

    updateInB(flag){

        super.updateInB(flag, ()=>{

            this.#xorGate.updateIn2(flag)

            this.#andGate.updateIn2(flag)

            return this.#returnOutArray()

        })

    }

    updateBothIn(inA, inB){

        super.updateBothIn(inA, inB, ()=>{

            this.#xorGate.updateBothIn(inA, inB)

            this.#andGate.updateBothIn(inA, inB)

            return this.#returnOutArray()

        })

    }

}

class FullAdder extends Adder{

    #inC

    #halfAdder1

    #halfAdder2

    #orGate

    constructor(id, inA = false, inB = false, inC = false){

        var halfAdder1 = new HalfAdder(undefined, inA, inB)

        var halfAdder2 = new HalfAdder(undefined, inC, halfAdder1.getOutS())

        var orGate = new OrGate(undefined, halfAdder1.getOutC(), halfAdder2.getOutC())

        super(id, inA, inB, halfAdder2.getOutS(), orGate.getOut())

        this.#inC = inC

        this.#halfAdder1 = halfAdder1

        this.#halfAdder2 = halfAdder2

        this.#orGate = orGate

        this.#halfAdder1.setOutSReceiver(halfAdder2, "inB")

        this.#halfAdder1.setOutCReceiver(orGate, "in1")

        this.#halfAdder2.setOutCReceiver(orGate, "in2")

    }

    #returnOutArray(){

        return [this.#halfAdder2.getOutS(), this.#orGate.getOut()]

    }

    updateInA(flag){

        super.updateInA(flag, ()=>{

            this.#halfAdder1.updateInA(flag)

            return this.#returnOutArray()

        })

    }

    updateInB(flag){

        super.updateInB(flag, ()=>{

            this.#halfAdder1.updateInB(flag)

            return this.#returnOutArray()

        })

    }

    updateInC(flag){

        this.#inC = flag

        this.#halfAdder2.updateInA(flag)

        this.updateOutSAndOutC(()=>{

            return this.#returnOutArray()

        })

    }

    updateBothIn(inA, inB){

        super.updateBothIn(inA, inB, ()=>{

            this.#halfAdder1.updateBothIn(inA, inB)

            return this.#returnOutArray()

        })

    }

    updateThreeIn(inA, inB, inC){

        super.updateBothIn(inA, inB)

        this.#inC = inC

        this.#halfAdder1.updateBothIn(inA, inB)

        this.#halfAdder2.updateBothIn(inC, this.#halfAdder1.getOutS())

        this.#orGate.updateBothIn(this.#halfAdder1.getOutC(), this.#halfAdder2.getOutC())

 

        this.updateOutSAndOutC(()=>{

            return this.#returnOutArray()

        })

    }

    receive(inName, flag){

        super.receive(inName, flag)

        if(inName == "inC"){

            this.updateInC(flag)

        }

    }

}

class EightBitBinaryAdder{

    #inC

    #outC

    #lastOutC

    #inA

    #inB

    #outS

    #fullAdders

    #fullAdderNum

    #outCReceiver

    #outCReceiverInName

    #outCInOutSFlag

    constructor(outCInOutSFlag = false){

        this.#outCInOutSFlag = outCInOutSFlag

        this.#inC = false

        this.#fullAdderNum = 8

        this.#fullAdders = []

        this.#inA = []

        this.#inB = []

        for(var i = 0; i < this.#fullAdderNum; i++){

            this.#inA.push(false)

            this.#inB.push(false)

        }

        //新键8个全加器

        for(var i = 0; i < this.#fullAdderNum; i++){

            this.#fullAdders.push(new FullAdder("f" + i))

            if(i != 0){

                this.#fullAdders[i - 1].setOutCReceiver(this.#fullAdders[i], "inC")

            }

        }

        this.updateOut()

    }

    updateBothIn(arrayA, arrayB){

        // this.#inC = inC

        this.#inA = arrayA

        this.#inB = arrayB

        for(var i = 0; i < this.#fullAdderNum; i++){

            if(i == 0){

                this.#fullAdders[i].updateInC(this.#inC)

            }

            this.#fullAdders[i].updateBothIn(arrayA[i], arrayB[i])

        }

        this.updateOut()

    }

    //输出默认值

    updateOut(){

        this.#outS = []

        for(var i = 0; i < this.#fullAdderNum; i++){

            this.#outS.push(this.#fullAdders[i].getOutS())

            if(i == this.#fullAdderNum - 1){

                this.#lastOutC = this.#outC

                this.#outC = this.#fullAdders[i].getOutC()

                if(this.#lastOutC != this.#outC)

                    this.#sendOutC(this.#outC)

                if(this.#outCInOutSFlag)

                    this.#outS.push(this.#outC)

            }

        }

    }

    updateInC(flag){

        this.#inC = flag

        this.updateBothIn(this.#inA, this.#inB, flag)

    }

    receive(inName, flag){

        if(inName == "inC"){

            this.updateInC(flag)

        }

    }

    #sendOutC(flag){

        if(this.#outCReceiver){

            this.#outCReceiver.receive(this.#outCReceiverInName, flag)

        }

    }

    setOutCReceiver(outCReceiver, inName){

        this.#outCReceiver = outCReceiver

        this.#outCReceiverInName = inName

    }

    getOut(){

        return this.#outS

    }

}

class SixteenBitBinaryAdder{

    #inC

    #outC

    #lastOutC

    #inA

    #inB

    #outS

    #eightBitBinaryAdder1

    #eightBitBinaryAdder2

    #bitNum = 16

    #outCReceiver

    #outCReceiverInName

    #outCInOutSFlag

    constructor(outCInOutSFlag){

        this.#outCInOutSFlag = outCInOutSFlag

        this.#inC = false

        this.#eightBitBinaryAdder1 = new EightBitBinaryAdder()

        this.#eightBitBinaryAdder2 = new EightBitBinaryAdder()

        this.#inA = []

        this.#inB = []

        for(var i = 0; i < this.#bitNum; i++){

            this.#inA.push(false)

            this.#inB.push(false)

        }

        this.#eightBitBinaryAdder1.setOutCReceiver(this.#eightBitBinaryAdder2, "inC")

        this.updateOut()

    }

    updateBothIn(arrayA, arrayB){

        this.#inA = arrayA

        this.#inB = arrayB

        this.#eightBitBinaryAdder1.updateBothIn(arrayA.slice(0, 8), arrayB.slice(0, 8))

        this.#eightBitBinaryAdder2.updateBothIn(arrayA.slice(8), arrayB.slice(8))

        this.updateOut()

    }

    updateOut(){

        this.#outS = this.#eightBitBinaryAdder1.getOut().concat(this.#eightBitBinaryAdder2.getOut())

        //发送send(OutC)

    }

    getOut(){

        return this.#outS

    }

    //TODO

    // updateInC(flag){

    //     this.#inC = flag

    //     this.updateBothIn(this.#inA, this.#inB, flag)

    // }

    // receive(inName, flag){

    //     if(inName == "inC"){

    //         this.updateInC(flag)

    //     }

    // }

    #sendOutC(flag){

        if(this.#outCReceiver){

            this.#outCReceiver.receive(this.#outCReceiverInName, flag)

        }

    }

    setOutCReceiver(outCReceiver, inName){

        this.#outCReceiver = outCReceiver

        this.#outCReceiverInName = inName

    }

}

运行验证代码testModel.js

验证通过判据:后台没有打印输出异常。

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Test</title>

    <script src="../js/test/TestUtils.js"></script>

    <script src="../js/model.js"></script>

    <script src="../js/utils.js"></script>

</head>

<body>

    <script>

        var g1 = new NullGate("g1")

        var g2 = new NullGate("g2")

        var g3 = new NullGate("g3")

        var g4 = new NullGate("g4")

        var g5 = new NullGate("g5")

        var g6 = new NullGate("g6")

        g1.setOutReceiver(g2, "in")

        g2.setOutReceiver(g3, "in")

        g3.setOutReceiver(g4, "in")

        g4.setOutReceiver(g5, "in")

        g5.setOutReceiver(g6, "in")

        g1.updateIn(true)

        assertTrue(g6.getOut())

    </script>

    <script>

        //与门

        var andGate = new AndGate("a01")

        assertFalse(andGate.getOut())

        andGate.updateIn1(true)

        assertFalse(andGate.getOut())

        andGate.updateIn2(true)

        assertTrue(andGate.getOut())

        //或门

        var orGate = new OrGate("o01")

        assertFalse(orGate.getOut())

        orGate.updateIn1(true)

        assertTrue(orGate.getOut())

        orGate.updateIn2(true)

        assertTrue(orGate.getOut())

        //异或门

        var xorGate = new XorGate("x01")

        assertFalse(xorGate.getOut())

        xorGate.updateIn1(true)

        assertTrue(xorGate.getOut())

        xorGate.updateIn2(true)

        assertFalse(xorGate.getOut())

        xorGate.updateBothIn(false, true)

        assertTrue(xorGate.getOut())

    </script>

    <script>

        //半加器

        var ha = new HalfAdder("h01")

        assertFalse(ha.getOutS())

        assertFalse(ha.getOutC())

        ha.updateInB(true)

        assertTrue(ha.getOutS())

        assertFalse(ha.getOutC())

        ha.updateInA(true)

        assertFalse(ha.getOutS())

        assertTrue(ha.getOutC())

        ha.updateBothIn(true, false)

        assertTrue(ha.getOutS())

        assertFalse(ha.getOutC())

    </script>

    <script>

        //全加器

        var fa = new FullAdder("fa01")

        assertFalse(fa.getOutC())

        assertFalse(fa.getOutS())

        function test(inA, inB, inC, expectedS, expectedC){

            fa.updateThreeIn(inA, inB, inC)

            if(expectedS)

                assertTrue(fa.getOutS())

            else

                assertFalse(fa.getOutS())

            if(expectedC)

                assertTrue(fa.getOutC())

            else

                assertFalse(fa.getOutC())

        }

        test(false, false, false, false, false)

        test(false, true, false, true, false)

        test(true, false, false, true, false)

        test(true, true, false, false, true)

        test(false, false, true, true, false)

        test(false, true, true, false, true)

        test(true, false, true, false, true)

        test(true, true, true, true, true)

    </script>

    <script>

        for(var i = 0 ; i < 256; i++){

            assertIntEquals(i, lowEightBitArray2Int(int2LowEightBitArray(i)))

        }

    </script>

    <script>

        var ebba = new EightBitBinaryAdder(true)

        for(var i = 0; i < 256; i++){

            for(var j = 0; j < 256; j++){i

                ebba.updateBothIn(int2LowEightBitArray(i), int2LowEightBitArray(j))

                assertIntEquals(i + j, lowNineBitArray2Int(ebba.getOut()))

            }

        }

    </script>

    <script>

        for(var i = -128; i <= 127; i++){

            assertIntEquals(i, eightBitArray2Int(int2EightBitArray(i)))

        }

    </script>

    <script>

        var ebba = new EightBitBinaryAdder()

        for(var i = -64; i < 64; i++){

            for(var j = -64; j < 64; j++){

                ebba.updateBothIn(int2EightBitArray(i), int2EightBitArray(j))

                assertIntEquals(i + j, eightBitArray2Int(ebba.getOut()))

            }

        }

    </script>

    <script>

        for(var i = -(1<<15); i <= (1<<15) - 1; i++){

            assertIntEquals(i, sixteentBitArray2Int(int2SixteenBitArray(i)))

        }

    </script>

    <script>

        var sbba = new SixteenBitBinaryAdder()

        sbba.updateBothIn(int2SixteenBitArray(1156), int2SixteenBitArray(9999))

        assertIntEquals(9999 + 1156, sixteentBitArray2Int(sbba.getOut()))

        //‭16384‬ * ‭16384‬ = 268435456 如果这样算会十分耗时

        // for(var i = -(1<<14); i < (1<<14); i++){

        //     for(var j = -(1<<14); j < (1<<14); j++){

        //         sbba.updateBothIn(int2SixteenBitArray(i), int2SixteenBitArray(j))

        //         assertIntEquals(i + j, sixteentBitArray2Int(sbba.getOut()))

        //     }

        // }

        for(var i = -100; i < 100; i++){

            for(var j = -100; j < 100; j++){

                sbba.updateBothIn(int2SixteenBitArray(i), int2SixteenBitArray(j))

                assertIntEquals(i + j, sixteentBitArray2Int(sbba.getOut()))

            }

        }

    </script>

</body>

</html>

到此,关于“JavaScript实现串行加法器的代码是什么”的学习就结束了,希望能够解决大家的疑惑,另外大家动手实践也很重要,对大家加深理解和学习很有帮助。

(编辑:银川站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章