28 - 算术运算指令

news2024/11/25 4:17:53

---- 整理自B站UP主 踌躇月光 的视频

文章目录

  • 1. ALU改进
  • 2. CPU 整体电路
  • 3. 程序
  • 4. 实验结果

1. ALU改进

此前的 ALU:

请添加图片描述

改进后的 ALU:

请添加图片描述

2. CPU 整体电路

请添加图片描述

3. 程序

# pin.py

MSR = 1
MAR = 2
MDR = 3
RAM = 4
IR = 5
DST = 6
SRC = 7
A = 8
B = 9
C = 10
D = 11
DI = 12
SI = 13
SP = 14
BP = 15
CS = 16
DS = 17
SS = 18
ES = 19
VEC = 20
T1 = 21
T2 = 22


MSR_OUT = MSR
MAR_OUT = MAR
MDR_OUT = MDR
RAM_OUT = RAM
IR_OUT = IR
DST_OUT = DST
SRC_OUT = SRC
A_OUT = A
B_OUT = B
C_OUT = C
D_OUT = D
DI_OUT = DI
SI_OUT = SI
SP_OUT = SP
BP_OUT = BP
CS_OUT = CS
DS_OUT = DS
SS_OUT = SS
ES_OUT = ES
VEC_OUT = VEC
T1_OUT = T1
T2_OUT = T2

_DST_SHIFT = 5

MSR_IN = MSR << _DST_SHIFT
MAR_IN = MAR << _DST_SHIFT
MDR_IN = MDR << _DST_SHIFT
RAM_IN = RAM << _DST_SHIFT
IR_IN = IR << _DST_SHIFT
DST_IN = DST << _DST_SHIFT
SRC_IN = SRC << _DST_SHIFT
A_IN = A << _DST_SHIFT
B_IN = B << _DST_SHIFT
C_IN = C << _DST_SHIFT
D_IN = D << _DST_SHIFT
DI_IN = DI << _DST_SHIFT
SI_IN = SI << _DST_SHIFT
SP_IN = SP << _DST_SHIFT
BP_IN = BP << _DST_SHIFT
CS_IN = CS << _DST_SHIFT
DS_IN = DS << _DST_SHIFT
SS_IN = SS << _DST_SHIFT
ES_IN = ES << _DST_SHIFT
VEC_IN = VEC << _DST_SHIFT
T1_IN = T1 << _DST_SHIFT
T2_IN = T2 << _DST_SHIFT

SRC_R = 2 ** 10
SRC_W = 2 ** 11
DST_R = 2 ** 12
DST_W = 2 ** 13

PC_WE = 2 ** 14
PC_CS = 2 ** 15
PC_EN = 2 ** 16

PC_OUT = PC_CS
PC_IN = PC_CS | PC_WE
PC_INC = PC_CS | PC_WE | PC_EN

_OP_SHIFT = 17
OP_ADD = 0 << _OP_SHIFT
OP_SUB = 1 << _OP_SHIFT
OP_INC = 2 << _OP_SHIFT
OP_DEC = 3 << _OP_SHIFT
OP_AND = 4 << _OP_SHIFT
OP_OR  = 5 << _OP_SHIFT
OP_XOR = 6 << _OP_SHIFT
OP_NOT = 7 << _OP_SHIFT

ALU_OUT = 1 << 20
ALU_PSW = 1 << 21

CYC = 2 ** 30
HLT = 2 ** 31

# - 二地址指令IR对应
#     - 1xxx [aa][bb]
# - 一地址指令IR对应
#     - 01xx xx[aa]
# - 零地址指令IR对应
#     - 00xx xxxx
ADDR2 = 1 << 7
ADDR1 = 1 << 6

ADDR2_SHIFT = 4
ADDR1_SHIFT = 2

AM_INS = 0 # 立即寻址 instant
AM_REG = 1 # 寄存器寻址
AM_DIR = 2 # 直接寻址 direct
AM_RAM = 3 # 寄存器间接寻址

# assembly.py

import pin

FETCH = [
    pin.PC_OUT | pin.MAR_IN,
    pin.RAM_OUT | pin.IR_IN | pin.PC_INC,
    pin.PC_OUT | pin.MAR_IN,
    pin.RAM_OUT | pin.DST_IN | pin.PC_INC,
    pin.PC_OUT | pin.MAR_IN,
    pin.RAM_OUT | pin.SRC_IN | pin.PC_INC,
]

MOV = (0 << pin.ADDR2_SHIFT) | pin.ADDR2 # MOV指令定义为 1000 xxxx
ADD = (1 << pin.ADDR2_SHIFT) | pin.ADDR2 # ADD指令定义为 1001 xxxx
SUB = (2 << pin.ADDR2_SHIFT) | pin.ADDR2

INC = (0 << pin.ADDR1_SHIFT) | pin.ADDR1
DEC = (1 << pin.ADDR1_SHIFT) | pin.ADDR1

NOP = 0
HLT = 0x3f

INSTRUCTIONS = {
    2: { # 二地址指令
        MOV: { # MOV指令寻址方式
            (pin.AM_REG, pin.AM_INS): [ # (寄存器寻址,立即寻址) ==> MOV A,5
                pin.DST_W | pin.SRC_OUT, # 微指令:读取SRC寄存器里数据(5)送入DST指定的寄存器(A)中
            ],
            (pin.AM_REG, pin.AM_REG): [ # MOV A, B
                pin.DST_W | pin.SRC_R # 写寄存器(A),读寄存器(B)
            ],
            (pin.AM_REG, pin.AM_DIR): [ # MOV A, [5]
                pin.SRC_OUT | pin.MAR_IN, # 从SRC寄存器读,送到MAR寄存器(RAM地址上)
                pin.DST_W | pin.RAM_OUT # 读取RAM指定地址的数据,写到寄存器(A),
            ],
            (pin.AM_REG, pin.AM_RAM): [ # MOV A, [B]
                pin.SRC_R | pin.MAR_IN, # 读取寄存器(B)数据,送到MAR寄存器(RAM地址上)
                pin.DST_W | pin.RAM_OUT # 读取RAM指定地址的数据,写到寄存器(A)
            ],
            (pin.AM_DIR, pin.AM_INS): [ # MOV [0x2f], 5
                pin.DST_OUT | pin.MAR_IN, # 读取DST寄存器数据,送到MAR寄存器(RAM地址上)
                pin.RAM_IN | pin.SRC_OUT # 从SRC寄存器读取数据5,写入RAM中
            ],
            (pin.AM_DIR, pin.AM_REG): [ # MOV [0x2f], A
                pin.DST_OUT | pin.MAR_IN,
                pin.RAM_IN | pin.SRC_R
            ],
            (pin.AM_DIR, pin.AM_DIR): [ # MOV [0x2f], [0x2e]
                pin.SRC_OUT | pin.MAR_IN,
                pin.RAM_OUT | pin.T1_IN,
                pin.DST_OUT | pin.MAR_IN,
                pin.RAM_IN | pin.T1_OUT
            ],
            (pin.AM_DIR, pin.AM_RAM): [ # MOV [0x2f], [A]
                pin.SRC_R | pin.MAR_IN,
                pin.RAM_OUT | pin.T1_IN,
                pin.DST_OUT | pin.MAR_IN,
                pin.RAM_IN | pin.T1_OUT
            ],
            
            (pin.AM_RAM, pin.AM_INS): [ # MOV [A], 5
                pin.DST_R | pin.MAR_IN,
                pin.RAM_IN | pin.SRC_OUT
            ],
            (pin.AM_RAM, pin.AM_REG): [ # MOV [A], B
                pin.DST_R | pin.MAR_IN,
                pin.RAM_IN | pin.SRC_R
            ],
            (pin.AM_RAM, pin.AM_DIR): [ # MOV [A], [0x30]
                pin.SRC_OUT | pin.MAR_IN,
                pin.RAM_OUT | pin.T1_IN,
                pin.DST_R | pin.MAR_IN,
                pin.RAM_IN | pin.T1_OUT
            ],
            (pin.AM_RAM, pin.AM_RAM): [ # MOV [A], [B]
                pin.SRC_R | pin.MAR_IN,
                pin.RAM_OUT | pin.T1_IN,
                pin.DST_R | pin.MAR_IN,
                pin.RAM_IN | pin.T1_OUT
            ],
        },
        ADD: {
            (pin.AM_REG, pin.AM_INS): [ # ADD D, 5
                pin.DST_R | pin.A_IN,
                pin.SRC_OUT | pin.B_IN,
                pin.OP_ADD | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
            (pin.AM_REG, pin.AM_REG): [ # ADD D, C
                pin.DST_R | pin.A_IN,
                pin.SRC_R | pin.B_IN,
                pin.OP_ADD | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
        },
        SUB: {
            (pin.AM_REG, pin.AM_INS): [ # SUB D, 5
                pin.DST_R | pin.A_IN,
                pin.SRC_OUT | pin.B_IN,
                pin.OP_SUB | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
            (pin.AM_REG, pin.AM_REG): [ # SUB D, C
                pin.DST_R | pin.A_IN,
                pin.SRC_R | pin.B_IN,
                pin.OP_SUB | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
        },
    },
    1: {
        INC: {
            pin.AM_REG: [
                pin.DST_R | pin.A_IN,
                pin.OP_INC | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
        },
        DEC: {
            pin.AM_REG: [
                pin.DST_R | pin.A_IN,
                pin.OP_DEC | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
        },
    }, # 一地址指令
    0: { # 零地址指令
        NOP: [
            pin.CYC, # 让指令周期清零,跳过这次指令
        ],
        HLT: [
            pin.HLT, # 指令停止
        ]
    }
}

# print(bin(MOV))
# controller.py

import os
import pin
import assembly as ASM

dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'micro.bin')

micro = [pin.HLT for _ in range(0x10000)]

def compile_addr2(addr, ir, psw, index):
    global micro
    
    # addr ==> | IR | PSW | CYC |
    # 二地址指令IR对应 ==> 1xxx [aa][bb]
    op = ir & 0xf0
    amd = (ir >> 2) & 3 # [aa] 寻址方式
    ams = ir & 3 # [bb] 寻址方式
    
    INST = ASM.INSTRUCTIONS[2]
    if op not in INST:
        micro[addr] = pin.CYC
        return
    am = (amd, ams)
    if am not in INST[op]:
        micro[addr] = pin.CYC
        return
    
    EXEC = INST[op][am] # 找到IR和寻址方式
    if index < len(EXEC): # 补到FETCH后面
        micro[addr] = EXEC[index]
    else:
        micro[addr] = pin.CYC

# 01xx xx[bb]
def compile_addr1(addr, ir, psw, index):
    global micro
    
    # addr ==> | IR | PSW | CYC |
    # 一地址指令IR对应 ==> 01xx xx[bb]
    op = ir & 0xfc
    amd = ir & 3 # [bb] 寻址方式
    
    INST = ASM.INSTRUCTIONS[1]
    if op not in INST:
        micro[addr] = pin.CYC
        return
    if amd not in INST[op]:
        micro[addr] = pin.CYC
        return
    
    EXEC = INST[op][amd] # 找到IR和寻址方式
    if index < len(EXEC): # 补到FETCH后面
        micro[addr] = EXEC[index]
    else:
        micro[addr] = pin.CYC

# 00xx xxxx
def compile_addr0(addr, ir, psw, index):
    global micro
    
    op = ir

    INST = ASM.INSTRUCTIONS[0]
    if op not in INST:
        micro[addr] = pin.CYC
        return
    
    EXEC = INST[op]
    if index < len(EXEC):
        micro[addr] = EXEC[index]
    else:
        micro[addr] = pin.CYC

for addr in range(0x10000): # 指令集处理
    # | IR | PSW | CYC |
    #   8     4     4
    ir = addr >> 8
    psw = (addr >> 4) & 0xf
    cyc = addr & 0xf
    
    # 先处理 取指指令FETCH
    if cyc < len(ASM.FETCH):
        micro[addr] = ASM.FETCH[cyc]
        continue
    
    addr2 = ir & (1 << 7) # 二地址
    addr1 = ir & (1 << 6) # 一地址
    
    index = cyc - len(ASM.FETCH) # FETCH占据了前面的位置,这里表示FETCH后面
    
    if addr2:
        compile_addr2(addr, ir, psw, index) # 处理二地址
    elif addr1:
        compile_addr1(addr, ir, psw, index) # 处理一地址
    else:
        compile_addr0(addr, ir, psw, index) # 处理零地址

with open(filename, 'wb') as file:
    for var in micro:
        value = var.to_bytes(4, byteorder='little')
        file.write(value)

print('Compile micro instruction finish!!!')

# compiler.py

import os
import re # re模块提供了各种各样的正则表达式方法
import pin
import assembly as ASM

dirname = os.path.dirname(__file__)

inputfile = os.path.join(dirname, 'program.asm')
outputfile = os.path.join(dirname, 'program.bin')

annotation = re.compile(r"(.*?);.*") # 这个正则表达式的目的是捕获分号;之前的所有内容

codes = []

OP2 = {
    'MOV': ASM.MOV,
    'ADD': ASM.ADD,
    'SUB': ASM.SUB
}

OP1 = {
    'INC': ASM.INC,
    'DEC': ASM.DEC
}

OP0 = {
    'NOP': ASM.NOP,
    'HLT': ASM.HLT,
}

OP2SET = set(OP2.values())
OP1SET = set(OP1.values())
OP0SET = set(OP0.values())

REGISTERS = {
    "A": pin.A,
    "B": pin.B,
    "C": pin.C,
    "D": pin.D,
}

class Code(object):
    def __init__(self, number, source):
        self.numer = number # 行号
        self.source = source.upper() # 源代码
        self.op = None
        self.dst = None
        self.src = None
        self.prepare_source() # 调用预处理源代码
    
    def get_op(self):
        if self.op in OP2:
            return OP2[self.op]
        if self.op in OP1:
            return OP1[self.op]
        if self.op in OP0:
            return OP0[self.op]
        raise SyntaxError(self)

    def get_am(self, addr): # 获取目的操作数和源操作数
        if not addr:
            return None, None
        if addr in REGISTERS: # 如果是寄存器,返回寄存器编码。示例就是A寄存器
            return pin.AM_REG, REGISTERS[addr]
        if re.match(r'^[0-9]+$', addr): # 如果是数字,返回立即数。示例就是5
            return pin.AM_INS, int (addr)
        if re.match(r'^0X[0-9A-F]+$', addr): # 如果是十六进制数,返回十六进制立即数
            return pin.AM_INS, int(addr, 16)
        match = re.match(r'^\[([0-9]+)\]$', addr)
        if match:
            return pin.AM_DIR, int(match.group(1))
        match = re.match(r'^\[(0X[0-9A-F]+)\]$', addr)
        if match:
            return pin.AM_DIR, int(match.group(1), 16)
        match = re.match(r'^\[(.+)\]$', addr)
        if match and match.group(1) in REGISTERS:
            return pin.AM_RAM, REGISTERS[match.group(1)]
        
        raise SyntaxError(self)
        
    def prepare_source(self): # 预处理汇编代码,以MOV A,5举例
        tup = self.source.split(',') # 用逗号分隔
        if len(tup) > 2:
            raise SyntaxError(self)
        if len(tup) == 2:
            self.src = tup[1].strip() # 5赋值给源操作数
        
        tup = re.split(r" +", tup[0]) # 正则表达式,将tup[0]字符串中的一个或多个连续空格作为分隔符,将字符串拆分成多个部分,并返回一个包含拆分后的所有部分的列表。将 MOV A拆分成了MOV和A
        if len(tup) > 2:
            raise SyntaxError(self)
        if len(tup) == 2:
            self.dst = tup[1].strip() # A赋值给了目的操作数
        
        self.op = tup[0].strip() # MOV赋值给指令
    
    def compile_code(self):
        # 指令IR ==> op + amd + ams
        # MOV ==> 1000 + [aa] + [bb]
        op = self.get_op()
        amd, dst = self.get_am(self.dst) # 预处理之后已经拿到self.dst=A
        ams, src = self.get_am(self.src) # 预处理之后已经拿到self.src=5
        
        if src is not None and (amd, ams) not in ASM.INSTRUCTIONS[2][op]:
            raise SyntaxError(self)
        if src is None and dst and amd not in ASM.INSTRUCTIONS[1][op]:
            raise SyntaxError(self)
        if src is None and dst is None and op not in ASM.INSTRUCTIONS[0]:
            raise SyntaxError(self)
        
        amd = amd or 0
        ams = ams or 0
        dst = dst or 0
        src = src or 0
        
        if op in OP2SET:
            ir = op | (amd << 2) | ams
        elif op in OP1SET:
            ir = op | amd
        else:
            ir = op
        
        return [ir, dst, src]
    
    def __repr__(self):
        return f'[{self.numer}] - {self.source}'

class SyntaxError(Exception):
    def __init__(self,code: Code, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.code = code

def compile_program():
    with open(inputfile, encoding='utf8') as file: # 打开汇编源码
        lines = file.readlines()
    
    for index, line in enumerate(lines):
        source = line.strip() # 将两端的空格去掉
        if ';' in source: # 将;后面的去掉
            match = annotation.match(source) # 使用之前定义的正则表达式annotation来匹配分号之前的内容
            source = match.group(1)
        if not source: # 检查source是否为空或只包含空白字符(例如空格、制表符、换行符等)
            continue
        code = Code(index + 1, source) # 传入行号和每行的汇编代码
        codes.append(code)
    
    with open(outputfile, 'wb') as file:
        for code in codes:
            values = code.compile_code()
            for value in values:
                result = value.to_bytes(1, byteorder='little')
                file.write(result)

def main():
    try:
        compile_program()
    except SyntaxError as e:
        print(f'Syntax error at {e.code}')
        return

    print('compile program.asm finished!!!')
        
if __name__ == '__main__':
    main()
# program.asm

; ; 1
; MOV D, 1;
; ADD D, 5;

; ; 2
; MOV D, 4
; MOV C, 7
; ADD D, C 

; ; 3
; MOV D, 250
; MOV C, 250
; ADD D, C 

; ; 4
; MOV D, 0
; MOV C, 0
; ADD D, C 

; ; 5
; MOV D, 5
; SUB D, 5

; 6
MOV D, 0;
INC D;
INC D;
INC D;
INC D;
INC D;

; DEC D
; DEC D
; DEC D
; DEC D
; DEC D

HLT

4. 实验结果

依次将 3. 中的几种情况的注释打开,编译运行,这里只给出最后一次的结果。

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1647192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity 性能优化之图片优化(八)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、可以提前和美术商量的事1.避免内存浪费&#xff08;UI图片&#xff0c;不是贴图&#xff09;2.提升图片性能 二、图片优化1.图片Max Size修改&#x…

OpenCampass评测实战 作业

按照如下教程文档操作即可&#xff1a;https://aicarrier.feishu.cn/wiki/NxUOwnLuvi0clykyzj7ccSHPndb

基于52单片机的AS608指纹密码锁电路原理图+源程序+PCB实物制作

目录 1、前言 2、实物图 3、PCB图 4、原理图 5、程序 资料下载地址&#xff1a;基于52单片机的AS608指纹密码锁电路原理图源程序PCB实物制作 1、前言 这是一个基于AS608STC89C52单片机的指纹识别和键盘密码锁。 里面包括程序&#xff0c;原理图&#xff0c;pcb图和实…

拉普拉斯丨独家冠名2024年度ATPV技术分论坛,助力产业科技持续创新

为了进一步促进行业技术交流&#xff0c;推进光伏行业发展及标准建设的进程&#xff0c;针对高效电池&#xff0c;领跑组件&#xff0c;新产品认证及应用等技术专题及国内外光伏标准的最新进程&#xff0c;由中国绿色供应链联盟光伏专委会&#xff08;ECOPV&#xff09;指导的2…

Linux安装Python3.9环境

大家好&#xff0c;今天给大家分享一下在Linux系统中安装Python3环境&#xff0c;Linux系统中自带的Python2尽量不要删除&#xff0c;删除后可能会导致系统出现问题。 关于Linux常用命令&#xff0c;可以参考&#xff1a;作为测试人员的Linux常用命令 一、下载Python3安装包 …

笔试强训Day17 字符串 前缀和

BC45 小乐乐改数字 题目链接&#xff1a;小乐乐改数字_牛客题霸_牛客网 (nowcoder.com) 思路&#xff1a; 水题一道 注意前导0. AC code&#xff1a; #include <iostream> #include<string> using namespace std; string a,b; int main() {cin >> a;for…

【Linux系列】tail查询使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Springboot集成Mybatispuls操作mysql数据库-03

MyBatis-Plus&#xff08;简称MP&#xff09;是一个MyBatis的增强工具&#xff0c;在MyBatis的基础上只做增强而不做改变。它支持所有MyBatis原生的特性&#xff0c;因此引入MyBatis-Plus不会对现有的MyBatis构架产生任何影响。MyBatis-Plus旨在简化开发、提高效率&#xff0c;…

yum常用命令与lrzsz的在线安装

yum命令 yum&#xff08; Yellow dog Updater, Modified&#xff09;是一个在 Fedora 和 RedHat 以及 SUSE 中的 Shell 前端软件包管理器。 基于 RPM 包管理&#xff0c;能够从指定的服务器自动下载 RPM 包并且安装&#xff0c;可以自动处理依赖性关系&#xff0c;并且一次安装…

python数据分析所需要的语法基础

Python语言基础——语法基础 前言语法基础变量标识符数据类型输入与输出代码缩进与注释 总结 前言 对于学过C语言的人来说&#xff0c;python其实很简单。学过一种语言&#xff0c;学习另一种语言&#xff0c;很显然的能感觉到&#xff0c;语言大体上都是相通的。当然&#xf…

nacos开启登录开关启动报错“Unable to start embedded Tomcat”

nacos 版本&#xff1a;2.3.2 2.2.2版本之前的Nacos默认控制台&#xff0c;无论服务端是否开启鉴权&#xff0c;都会存在一个登录页&#xff1b;在之后的版本关闭了默认登录页面&#xff0c;无需登录直接进入控制台操作。在这里我们可以在官网可以看到相关介绍 而我现在所用的…

代码随想录-算法训练营day31【贪心算法01:理论基础、分发饼干、摆动序列、最大子序和】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第八章 贪心算法 part01● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和 贪心算法其实就是没有什么规律可言&#xff0c;所以大家了解贪心算法 就了解它没有规律的本质就够了。 不用花心思去研究其…

软件测试与管理-白盒测试-基本路径测试法

知识点&#xff1a; 1.原理 是在程序控制流图的基础上&#xff0c;通过分析控制构造的环路复杂性&#xff0c;导出基本可执行路径的集合&#xff0c;然后根据可执行路径进行测试用例设计的方法。此方法设计出的测试用例需保证被测程序的每个可执行语句至少执行一次。 2.步骤 &a…

Netty 实现dubbo rpc

一、RPC 的基本介绍 RPC (Remote Procedure Call) 远程过程调用&#xff0c;是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序&#xff0c;而程序员无需额外的为这个交互编程。也就是说可以达到两个或者多个应用程序部署在不同的服务器上&…

基于BP神经网络的QPSK解调算法matlab性能仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ........................................................................ for ij 1:leng…

神经网络中的归一化

我们今天介绍一下神经网络中的归一化方法~ 之前学到的机器学习中的归一化是将数据缩放到特定范围内&#xff0c;以消除不同特征之间的量纲和取值范围差异。通过将原始数据缩放到一个特定的范围内&#xff0c;比如[0,1]或者[-1,1]&#xff0c;来消除不同特征之间的量纲和取值范围…

弹性云服务器给用户带来了哪些便利

什么是弹性云服务器&#xff1f; 弹性云服务器&#xff08;ECS&#xff0c;Elastic Cloud Server&#xff09;简单地说&#xff0c;是指运行在云计算环境中的虚拟服务器。弹性云服务器可以说是虚拟专用服务器(VPS)&#xff0c;但VPS却不能说是云服务器。这是因为两者有着本质的…

软件游戏丢失XINPUT1_4.dll文件的多种解决方法分享

当玩家在尝试启动某款游戏时&#xff0c;遇到了系统提示“游戏找不到XINPUT1_4.dll”&#xff0c;这个错误通常发生在玩家尝试启动游戏时&#xff0c;游戏无法找到所需的XINPUT1_4.dll文件&#xff0c;呆滞无法正常启动运行。但是幸运的是&#xff0c;有一些简单的修复方法可以…

【typescript测试 - Jest 配置与使用】

安装 npm install --save-dev types/jestnpm install --save-dev ts-jest配置 tsconfig.json {"compilerOptions": {"types": ["jest"]} }jest.config.js module.exports {preset: ts-jest,testEnvironment: node, };使用 // add.js funct…

数据分析——业务指标量化

业务指标量化 前言一、统计指标二、统计指标特点完整的统计指标统计指标的理解和使用方法 三、统计指标类型总量指标时期指标时点指标总量指标的作用 相对指标计划完成相对数指标结构相对数指标比例相对数指标比较相对数指标动态相对数指标 平均指标 四、数量指标和质量指标五、…