大家新年好,我是呼噜噜,在上一篇简易加法器里我们了解了半加器和全加器的设计与实现,今天我们来看下CPU中减法器是如何实现的。文章比较长,大家可以收藏反复观看
我们来看一个最常见的例子,2-1 =1
这是减法,但它等同于 2+ (-1) =1
这其实是加法。从运算逻辑上来说,减法可以通过加法来实现,这是可行的。
从硬件电路层面说,我们很容易让电子实现汇总的效果,但是将电子群拆分出多个更小的集群,是不容易的。还有一个好处是利用加法器能实现减法的效果的话,就不需要再为减法器专门设计电路了,降低了电路的复杂度。
由于计算机采用的是二进制,和我们天生熟悉的十进制还是有区别的,那么二进制能否实现用加法来实现减法效果?
很幸运地是,当初那群计算机那群工程师大拿将二进制玩的是炉火纯青,通过原码->反码->补码
,一步步实现了二进制通过加法来实现减法效果。其中原理大家感兴趣地,可以看看笔者之前的一篇文章 计算机中数值和字符串怎么用二进制表示?
补码真的是一个天生完美的奇妙存在,基于补码的机制,减法可以转化为加法,也就意味着计算机可以通过加法器实现减法。
看完笔者的那篇文章,我们知道了补码产生的手动:正数原码不变,负数的符号位不变, 其余各位取反, 最后一位+1
要实现原码到补码的转换,需要一个取反器,我们先来写出减法逻辑的真值表:
通过真值表,我们可以很容易发现这其实就是一个异或门(相同为0,不同为1)
我们来实现一个8位的取反器,由于是8位的,所以输入选这8位输入,还得连一个8位的分线器,输出类似。异或门得有8个,每个都需和控制是否取反的输入相连。
我们将之前的全加器和减法器结合起来,需要注意的是补码需要取反再+1
,取反可以将输入和取反器相连,+1
可以将全加器最低位的进位与控制取反的输入相连即可,极简单又巧妙
我们来启动模拟,看下效果:
上图计算结果,相当于:
1+1 =2
1-1 =0
但是上面有个问题是,1-1=0
时,虽然灯泡是0,但是旁边的溢出标志显示溢出了,我们还需改造一下。我们这里简单地,就直接让减法不溢出即可(这种处理方式还是比较粗暴的,但是实现起来比较简单)
我们来写出溢出输入IY,是否取反输入IF(如果取反,就代表是减法操作),溢出输出O的真值表关系
IY | IF | O |
---|---|---|
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 0 |
0 | 1 | 0 |
我们可以推出公式:O=非IF * IY
,所以需要非门和与门
这样就减法时,就不会溢出了。但其实这个加法器只能做正数的减法(也就是输入A得大于等于输入B),如果最后结果为负数的,还是有bug的。我们后面有机会再优化
由于用灯泡表示二进制,每次得出的结果,还要我们去换算成10进制,非常不直观,我们接下来利用数码管,来将二进制数"翻译"成10进制数。
我们这边利用的是7段数码管来实现的,数码管其实就是多个LED灯,不同的位控制不同的LED。从第0位到第7位,通过控制不同的LED来组合出数字。第7位比较特殊,数码管显示的是点
我们用上面的电路,一一将0~F16个数显示出来,各个开关的情况记录成下面的表:
数值 | 开关(2进制) | HEX(16进制) |
---|---|---|
0 | 0011 1111 | 0x3F |
1 | 0011 0000 | 0x06 |
2 | 0101 1011 | 0x5B |
3 | 0100 1111 | 0x4F |
4 | 0110 0110 | 0x66 |
5 | 0110 1101 | 0x6D |
6 | 0111 1101 | 0x7D |
7 | 0000 0111 | 0x07 |
8 | 0111 1111 | 0x7F |
9 | 0110 1111 | 0x6F |
A | 0111 0111 | 0x77 |
b | 0111 1100 | 0x7C |
C | 0011 1001 | 0x39 |
D | 0101 1100 | 0x5E |
E | 0111 1001 | 0x79 |
F | 0111 0001 | 0x71 |
这其实就是7段数码管的共阴极对照表,还有共阳极对照表这里我们就不展示了。
如果直接用组合电路来封装8位输入,7段数码管的16进制显示,的确是可以的,但如果是16位,32位,64位输入,电路会异常的复杂,我们这边用储存器ROM来实现这个功能
ROM只读存储器,是以非破坏性读出方式工作,它非易失性存储器,当电源被移除时,其数据内容不会被擦除,它还有个特点就是只能读出而不能写入信息,其所存的数据,一般是装入整机前事先写好的,整机工作过程中只能读出。
需要注意的是: 虽然ROM和硬盘有一些共性,但不能简单地说ROM就是硬盘
常常与ROM相比的还有一个RAM(随机存取存储器),也就是我们常说的主存,是与CPU直接交换数据的内部存储器,它的特点:随机存取、数据易失、对静电敏感、访问速度快、需要刷新。RAM在断电以后保存在上面的数据会自动消失
我们使用ROM和7段数码管来显示16进制的数0~F,选用地址位宽为4,数据位宽为8,只需把对应的数据提前写入对应的地址中即可。
这里需要注意一下,为什么我们选用地址位宽为4,数据位宽为8的ROM?
首先我们需要明白(1111 1111)2 = (f f)16
, 7段数码管可以表示0~F 16进制数,我们可以用2个7段数码管并联将8位二进制数译码成16进制数。
我们就先考虑1个7段数码管和ROM的关系,单个"f"也就是第16个数,也就是说4位二进制,即4位输入,最大值为16
我们想显示16进制数,0~F,我们需要4位二进制输入,其最大值1111
,就是16(F),结合上面的共阴极对照表,我们就能总结下面的表:
A3 | A2 | A1 | A0 | Number | HEX(16进制) |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0x3F |
0 | 0 | 0 | 1 | 1 | 0x06 |
0 | 0 | 1 | 0 | 2 | 0x5B |
0 | 0 | 1 | 1 | 3 | 0x4F |
0 | 1 | 0 | 0 | 4 | 0x66 |
0 | 1 | 0 | 1 | 5 | 0x6D |
0 | 1 | 1 | 0 | 6 | 0x7D |
0 | 1 | 1 | 1 | 7 | 0x07 |
1 | 0 | 0 | 0 | 8 | 0x7F |
1 | 0 | 0 | 1 | 9 | 0x6F |
1 | 0 | 1 | 0 | A | 0x77 |
1 | 0 | 1 | 1 | b | 0x7C |
1 | 1 | 0 | 0 | C | 0x39 |
1 | 1 | 0 | 1 | d | 0x5E |
1 | 1 | 1 | 0 | E | 0x79 |
1 | 1 | 1 | 1 | F | 0x71 |
根据对应关系,我们把电路和存储器相应地址数据预先填进去
我们启动模拟看下效果:
测试完成后,将4个开关换成4位输入。接着我们将2个4位16进制译码器并联,就成了8位16进制译码器,并封装一下:
并将它与上文的全加器与减法器结合起来:
nice!
通过上一小节,我们成功把8位二进制数,"翻译"成16进制数,但距离我们更熟悉的十进制还是有点距离的,我们本小节继续改进7段数码管,实现10进制的译码
由于(1111 1111)2 = (255)10
, 最大值为255
ROM需要8位地址位宽,2^8 = 256
,确保能够将256个数(0 ~255)全部找到;255是3位数,我们至少需要3个数码管(也就是我们上一小节封装的4位16进制译码管),1个数码管需要4位输入,所以ROM数码管的数据位宽为12
更多精彩文章在公众号「小牛呼噜噜」
电路实现:我们可以使用8个开关,来表示8位输入;选用8位地址位宽且数据位宽为12的ROM,通过8位3针脚的分线器和3个4位16进制译码管相连即可。
由于ROM的查找表有255个数,不能像之前一样一个个手动填写,我们可以利用Python来实现(电脑中需要有Python3的环境)。
将其另存到桌面上为test.bin文件,用vscode打开该文件(需要安装 hex editor插件来显示二进制),以小端显示:
test.py:
with open('test.bin', 'wb') as f:
for i in range(256):
var = str(i)
var = int(var, base=16) //先转成16进制
byte = var.to_bytes(2, byteorder='little')// 再转化成二进制,以显示小端
print(byte)
f.write(byte)
将其放到test.bin 同级目录后,直接运行命令python test,py
后,test.bin就变成了:
这种55 02
其实是 255
,31 02
为 231
, 像这种55 02
就是小端表示法。
将test.bin 重新加载到ROM中
我们来启动模拟看看:
我们将输入替换开关,然后封装成8位10进制译码器电路,接上之前的减法器的电路:
我们现在有个需求,001,前面的0不想要,就想要1
,我们借助21选择器来实现 高位为零时,数码管不亮
我们先来看一下1位21选择器,首先有2个输入,分别为A和B,以及一个有效位EN,一个输出S。我们的目的是实现:有效输出A,无效输出B。根据目的我们可以写出真值表:
EN | A | B | S |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 1 | 0 | 0 |
0 | 1 | 1 | 1 |
1 | 0 | 0 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
1 | 1 | 1 | 1 |
我们可以得出公式 S = EN与A + 非EN与B
,进而可以画出电路图
封装后,模拟一下:
我们继续画出8位21选择器,只需将8个1位21选择器组合在一起:
将其封装一下,接着模拟测试:
7段数码管10进制显示增强的电路,我们再重新设计一下:
更多精彩文章在公众号「小牛呼噜噜」
最后把其封装一下,放到减法器和加法器的电路中,演示一下:
完美,这样就实现了我们的目的。
本文我们将上一小篇文章中的简易加法器进行来改进,通过补码,让加法器也是运算减法。接着为了让我们观察结果更加方便,我们使用了7段数码管实现了 16进制、10进制显示,最终优化了10进制显示,使其只显示有效位的数值。
本系列到目前为止主要是组合逻辑电路的相关知识,后续我们会探究时序逻辑电路的奥秘,来看看开关究竟是如何实现CPU除计算功能外另一个重要的功能"记忆功能"。
参考资料:
全文完,感谢您的阅读,如果我的文章对你有所帮助的话,还请点个免费的赞,你的支持会激励我输出更高质量的文章,感谢!
原文镜像:http://mp.weixin.qq.com/s/QXWm-s-v3VuYV7s4-uE7yA
计算机内功、源码解析、科技故事、项目实战、面试八股等更多硬核文章,首发于公众号「小牛呼噜噜」,我们下期再见!
<imgsrc="https://markdownpicture.oss-cn-qingdao.aliyuncs.com/blog/20210925233820.png"width="500"height="400"alt="图片名称"align=center/>cglib动态代理cglib介绍CGLIB是一个开源项目,一个强大高性能高质量的代码生成库,可以在运行期拓展Java类,实现Java接口等等。底层是使用一个小而快的字节码处理框架ASM,从而转换字节码和生成新的类。理论上我们也可以直接用ASM来直接生成代码,但是要求我们对JVM内部,class文件格式,以及字节码的指令集都很熟悉。这玩意不在JDK的包里面,需要自己下载导入或者Maven坐标导入。我选择Maven导入,加到pom.xml文件:<dependencies> <dependency> <groupId>cglib</groupId> <artifactId>cglib
阅读目录(Content) 1、从蚂蚁行为说起 2、奖励和惩罚–超级反映倾向 3、喜欢/热爱倾向 4、讨厌/憎恨倾向 5、避免怀疑倾向 6、避免不一致倾向 7、好奇心倾向 8、康德式公平倾向 9、艳羡/妒忌倾向 10、回馈倾向 11、受简单联想影响的倾向 12、简单的、避免痛苦的心里否认 13、自视过高的倾向 14、过度乐观的倾向 15、被剥夺超级反应的倾向 16、社会认同倾向 17、对比错误反应倾向 18、压力影响倾向 19、错误衡量易得性倾向 20、不用就忘倾向 21、化学物质错误影响倾向 22、化衰老-错误影响倾向 23、权威-错误影响倾向 24、废话倾向 25、重视理由倾向1、从蚂蚁行为说起在开始综述理论之前,我们先讨论一个有助于理解以下内容的普遍观点。这个观点是从我们对社会性昆虫的了解中提炼出来的。这些昆虫很漂亮地证明了神经系统细胞在进化过程中固有的局限,它们整个神经系统通常只有10万个左右的细胞,而人类光是大脑的细胞就有上百亿个。蚂蚁和人类相比,都是由活体结构加上神经细胞中的行为程序组成的。就蚂蚁而言,其行为程序只有少数几种,而且几乎完全来自遗传。蚂蚁能够根据经验学到新的行
Tendis开发者线上交流会又来啦!在上次交流会的时候,嘉宾就为大家分享了Tendis的两种产品形态——存储版和混合存储版,分别对应了两种不同的需求,同时,嘉宾还为大家介绍了存储版的架构和特性,就在此后不久,晓多AI的运维总监冯浩在选择Tendis作为Redis存储场景的替代方案后,给出如下评价:“在进行开源软件选型时,我们不仅仅会考察产品能力是否符合业务需求和使用场景,同时还会重点关注社区活跃度、产品成熟度和稳定性、架构复杂度及运维便捷性等特性。因此,通过对Tendis前期调研和业务测试,最后(我们)综合决定选择Tendis作为Redis存储场景的替代方案,由于Tendis完全兼容Redis协议和数据结构,通过复用Redis生态的迁移工具,比如Redis-sync工具,大大降低了业务迁移成本,同时完美解决了大容量所带来的资源成本过高的问题。”相比Redis存储方案资源成本降低多达95%左右。因此,本次将会延续上次的直播内容,为大家带来《Tendis混合存储版架构及亮点特性揭秘》。Tendis第二次开发者线上交流会3月31日(周三),第二次Tendis开发者线上交流会,由腾讯专家为大家
在进行通道光谱图绘制前,需要先按照eeglab教程系列(2)-绘制脑电头皮图进行先操作(只需操作完第二步后点击OK即可)。绘制通道光谱图 在eeglab界面进行如下操作:Plot>Channelspectraandmaps,会打开pop_spectopo.m界面。根据需求设置参数,这里采用默认设置,点击OK,会跳转到spectopo.m界面:这幅图是在采样15%的数据得到的结果,[15%是在第一幅图中红框中设置]。也可以设置为100%,设置100%的效果图为: 上面图中,每个彩色记录道表示一个数据通道活动的频谱。最左边的头皮图显示了6赫兹时头皮的能量分布,这些数据集中在额叶中线。其他的头皮图显示了10赫兹和22赫兹的能量分布。想要看详细的信息,可以单击每个小图,比如单击6赫兹的脑图,会得到如下结果:可以操作:Plot>Channelproperties来绘制所选通道的头皮位置,其活动范围以及其活动在单个时期内的ERP图像。可以在红框处编辑通道数,这里填写通道1.点击OK出现如下界面:上图红色处为所选通道的头皮位置,上图还包括活动范围以及其活动在单个时期内的ERP图像。脑机接
目录用于二维手势估计的旋转不变混合图形模型网络从人体移动轨迹中学习具有空间层次的细粒度位置嵌入中等服装变化下基于轮廓草图的行人再识别基准成像系统的综合数据库基于双向语言模型的半监督序列标注用于二维手势估计的旋转不变混合图形模型网络论文名称:Rotation-invariantMixedGraphicalModelNetworkfor2DHandPoseEstimation作者:KongDeying/MaHaoyu/ChenYifei/XieXiaohui发表时间:2020/2/5论文链接:https://arxiv.org/abs/2002.02033v1推荐原因这篇论文发表于WACV2020,考虑的是二维手姿势估计问题。这篇论文提出了一种名为旋转不变混合图形模型网络(R-MGMN)的网络架构,用来解决单摄像头采集的RGB图像中的二维手姿势估计问题。通过集成一个旋转网络,R-MGMN可以应对图像中手的旋转。R-MGMN还具有一个图形模型库,可以根据输入图像来选择图形模型的组合。R-MGMN通过在每个图形模型上执行置信传播来生成一组边际分布,然后将这些边际分布作为手部关键点位置的置信度映
用户点击下载多媒体文件(图片/视频等),最简单的方式:<ahref='url'download="filename.ext">下载</a>复制如果url指向同源资源,是正常的。如果url指向第三方资源,download会失效,表现和不使用download时一致——浏览器能打开的文件,浏览器会直接打开,不能打开的文件,会直接下载。浏览器打开的文件,可以手动下载。解决方案一:将文件打包为.zip/.rar等浏览器不能打开的文件下载。解决方案二:通过后端转发,后端请求第三方资源,返回给前端,前端使用file-saver等工具保存文件。如果url指向的第三方资源配置了CORS,download依然无效,但可以通过xhr请求获取文件,然后下载到本地。/** *用FileSave保存文件 *@paramurl */ exportfunctiondownloadUrlFile(url){ constxhr=newXMLHttpRequest(); xhr.open('GET',url,true); xhr.respo
什么是MongoDBMongoDB 是一个基于分布式文件存储的数据库。MongoDB是个开源的NoSql数据库,其通过类似于JSON格式的数据存储,这使得它的结构就变得非常自由。通过MongoDB的查询语句就可以查询具体内容。 为什么使用MongoDB其实大部分原因只是因为MongoDB可以快速查找出结果,它大概可以达到10亿/秒。当然MongoDB很流行的另外一个原因是在很多应用场景下,关系型数据库是不适合的。例如,使用到非结构化,半自动化和多种状态的数据的应用,或者对数据可扩展性要求高的。 我们正在为开源项目提供免费测试,如果你想测试下你的开源程序,请点击这里。 案例分析第一个例子,我们有一个PHP页面。主要实现通过变量id获取到该id的username和password: 从代码可以知道,数据库名是security,集合名是users。u_id是通过GET请求传到后台,然后传入一个数组变量中。然后进入MongoDB的查询。我们试试通过数组传入运算符号 返回了数据库中的所有内容。看看我们传入的数据: http://localhost/mongo/show.php?u_id[$n
大家好,又见面了,我是你们的朋友全栈君。设计 Users表:UserID,Name Articles表:ArticleID,UserID,ArticleTitle 生成视图: SELECT dbo.Articles.ArticleID,dbo.Articles.ArticleTitle,dbo.Users.Name FROM dbo.Articles INNER JOIN dbo.Users ON dbo.Articles.UserID = dbo.Users.UserID写一条执行删除的StoredProcedure:CREATE PROCEDURE dbo.DeleteArticle @a int AS delete from Articles where ArticleID = @a RETURN在aspx页面上,增加GridView,并指定数据源SqlDataSource通过向导生成的SqlDataSource1: <asp:SqlDataSourceID=”SqlDataSource1″runat=”server” Connection
Dock应用的介绍:1.设计到的东西多2.使用swift设计3.Dock的代码量:200,000行4.更少的重写相同功能的代码swift.org官网介绍SwiftOpenSource三个分类:语言方面,包管理,核心库PackageManager frictionless核心库,在iOS,macOS等平台共用的代码FoundationonLinuxswift-evolutionapi-design-guideline命令方面泛型枚举typeCheckedSE-0081where在泛型中移动到语句最后返回值不需要_多文件一起编译,导致编译时间增加,然后呢,又想做缓存已经编译的.==!代码量减少,DemoBots(可以在SampleCode下载)Xcode的改变:Swift2.2+newSDK=Swift2.3
同义词=表的别名 语法:CREATE[PUBLIC]SYNONYM同义词名称FOR数据库对象; 示例一、 --使用管理员创建或者具有创建同义词权限的用户 --为scott创建同义词 CONNsys/change_on_installASSYSDBA; CREATESYNONYMmyempFORscott.emp --使用scott登录 select*frommyemp; --效果和以下相同 select*fromemp;复制 查询同义词是否创建成功 SELECT*FROMUser_Synonyms;复制 如果要创建公共的同义词只需要在前面加上public,这样任何有查询权限的用户都可以使用 使用管理员登录,并创建,公共同义词 CREATEPUBLICSYNONYMmyempFORscott.emp;复制 新建用户并登录或者,使用其它用户登录,都可以执行以下 --执行 SELECT*FROMmyemp;复制 删除同义词的语法DROPSYNONYM同义词名称 DROPSYNONYMmyemp;复制
题解区都什么大佬,根本看不懂~ 基本思路 图的环与点数\(\le50\)可以想到Floyd算法 本题的Floyd算法要干什么呢?更简单的,\(f(i,j)\)存什么呢? 如果说存\(i\rightarrowj\)的边权异或和,有人会问:这又不是一棵树,有好多条路径可以连接两点,这异或和会有很多种。 但不要忘了这是一张无向图,如果说\(i\rightarrowj\)有两种路径,但是他们的异或和不一样,暂时记作\(a,b\),那么\(a\\text{xor}\b\neq0\),可以直接输出No 所以说想要使得输出为Yes,图中两点间的异或和必定相等,只要所有点对\((u,v)\)都满足这一条件,本题就可以输出Yes啦~ 代码 #include<bits/stdc++.h> usingnamespacestd; constintN=50+5; intT,n,m; intf[N][N]; intmain(){ scanf("%d",&T); while(T--){ memset(f,-1,sizeof(f)); //初始化,未连边/未计算的初值均为-1
Hadoop进入安全模式有三个条件具体源码如下 privatebooleanneedEnter(){ //TODO-ZHDataNode汇报block状态为complete状态数量 return(threshold!=0&&blockSafe<blockThreshold)|| //TODO-ZH默认存活DataNode节点小于datanodeThreshold(默认为0) (datanodeThreshold!=0&&getNumLiveDataNodes()<datanodeThreshold)|| //TODO-ZH元数据存储磁盘空间是不充足 (!nameNodeHasResourcesAvailable()); } 复制 条件一:threshold!=0&&blockSafe<blockThreshold;DataNode汇报过来的complete的block个数占block总数是否达到设定阈值占比(默认0.99),若未达到此阈值则进入安全模式,计算complete状态数量如下 //TODO-ZH计算阈值 t
操作数栈(OperandStack)是栈帧中一个先入后出的栈,同局部变量表一样,栈的最大深度在编译期间就已确定,并在运行期间也不会改变。JVM虚拟机的解释引擎是基于栈的执行引擎,其中的栈就是操作数栈。操作数栈其实可以理解为方法执行时变量的临时存储区,存储类型与局部变量表一致,其中byte、short、char都会转为int类型,32位类型所占的栈容量为1,64位类型则占用栈容量为2(如long和double)。 一、执行原理 publicclassOperandStackDemo{ publicintadd(){ intx=2; inty=4; intz=x+y; returnz; } }复制 Code: stack=2,locals=4,args_size=1 0:iconst_2 1:istore_1 2:iconst_4 3:istore_2 4:iload_1 5:iload_2 6:iadd 7:istore_3 8:iload_3 9:ireturn复制 以上面的简单代码为例,通过javap得到字节码文件中的Code属
细胞分裂 细胞分裂有一个细胞每一个小时分裂一次,一次分裂一个子细胞,第三个小时后会死亡。那么n个小时候有多少细胞?这个问题的核心就是三个小时为一个周期 //每三个小时为一个周期,第四个小时就godie了。 //方法一 //第一个小时,只有a态细胞;第二个小时,a态细胞分裂,原来的a态细胞变成了b态细胞,分裂出来的细胞变成了新的a态细胞;第三个小时,a态细胞继续分裂变成b态细胞和新的a态细胞,b态细胞分裂变成c态细胞和a态细胞;第四个小时,a、b、c态细胞都会分裂,并且按照之前的规律转变。得出下面的结论 //a初始态一个小时前一个小时的a+b+c //b幼年态两个小时前一个小时的a //c成熟态三个小时前一个小时的b functionallCell(n){ //a态细胞 letaCell=function(n){ if(n==1){ return1; }else{ returnaCell(n-1)+bCell(n-1)+cCell(n-1); } } //b态细胞 letbCell=function(n){ if(n==1){ return0; }else{ return
修改日期为格式字符串 to_char(date,'yyyy/mm')复制 获取当前日期往前6个月 add_month(sysdate,-5)复制 orderby要放在groupby后面 SELECTFORMATDATE, DEALER, SUM(AMOUNT) FROMSHIPMENTS WHEREFORMATDATE>=TO_CHAR(ADD_MONTHS(SYSDATE-1,-5),'yy.mm') ANDFORMATDATE<=TO_CHAR(SYSDATE-1,'yy.mm') GROUPBYFORMATDATE, DEALER ORDERBYFORMATDATE;复制 除数不为0 在oracle除数不能为零 好吧,出了问题就得想法解决 例 selecta/baswwhere表复制 解 decode(b,0,null,a/b)复制 一般来说,我会在除法算式前加decode 这样如果b为0,则输出null,不为零则输出a/b Rank排名 selecte.ename,e.
idea 主要原理 模拟退火是一种求解多峰函数极值的随机化算法,适用性强,骗分功能强大。 解决多峰函数极值问题首先有一种贪心的方法,考虑每次选择当前值两端的值,如果有更优则将当前值变成更优值,最终到达峰顶,也叫爬山算法。可惜这种方法很容易受到步长限制,将答案局限在某一区间峰值中,无法跳出,导致无法到达全局峰值。 于是考虑将爬山的决策选取增加一些随机扰动,摆脱步长限制。这也就是我们模拟退火算法的原理。 先放一张经典原理图: 设初温为\(T_c\)(一般为一个千位数,具体情况具体分析),温度变化率为\(T_d\)(一般为\(0.95\)到\(0.99\)之间,略小于\(1\)),末温为\(T_e\)(一般在\(1e-6\)到\(1e-15\)之间,是一个极小的数)。 我们每次将温度乘上变化率,到达末温时停止。结合原理图可知,退火过程中,需要满足温度越高时,扰动越大,所选择的位置跳的范围越大,当温度逐渐降低时,扰动逐渐变小,所选择的位置跳的速度逐渐趋缓,最终稳定在最优解附近,到达全局极值。 实现流程 1.准备退火 退火之前,我们需要先设置好合适的初温、温度变化率、末温以及退火次数。 其中,
原文链接:20多个好用的Vue组件库 在本文中,将分享一些常见的vue.js组件。 Tables/DataGrids VueTables-2 地址:https://github.com/matfish2/vue-tables-2 VueTables2旨在为开发者提供一个功能齐全的工具集,以便用Vue创建漂亮而实用的数据表格。数百个商业软件应用正在使用它。此外,VueTables2正在不断成长、改进,同时也在获得新的功能。 特点如下: 可选行及粘性头部 虚拟分页 下载客户组件数据的CSV 有数据层支持的多级分组 Tailwind主题 Handsontable 地址:https://github.com/handsontable/handsontable/tree/master/wrappers/vue Handsontable是一款页面端的表格交互插件,可以通过它加载显示表格内容,能够支持合并项、统计、行列拖动等。 支持对加载后的表格页面的处理:添加/删除行/列,合并单元格等操作。 此外,它还适用于React、Angular和Vue。Handsontable是一个JavaS
备份原始source.list cp/etc/apt/sources.list/etc/apt/sources.list.back 复制 更新sources内容 debhttp://mirrors.aliyun.com/ubuntu/bionicmainrestricteduniversemultiverse deb-srchttp://mirrors.aliyun.com/ubuntu/bionicmainrestricteduniversemultiverse debhttp://mirrors.aliyun.com/ubuntu/bionic-securitymainrestricteduniversemultiverse deb-srchttp://mirrors.aliyun.com/ubuntu/bionic-securitymainrestricteduniversemultiverse debhttp://mirrors.aliyun.com/ubuntu/bionic-updatesmainrestricteduniversemultiverse deb-srchtt
EarlyUpdate.UpdatePreloading Loading.UpdatePreloading:在异步加载/卸载场景,异步加载AssetBundle,加载AssetBundle中的Asset,加载Resource文件夹中资源,调用UnloadUnusedAssets时会产生这个tag.如果加载操作要求等待完成,则会在子tag中看到AsyncOperationComplete,否则在子tag中会看到IntegrateAssetsInBackground UpdatePreloading:根据加载线程的优先级取得可用时间片,在时间片耗尽前,尝试最多次的加载资源。每次加载资源会产生一次kPreloadSingleSteptag。UnityPreloading的线程可用时间片每次为4ms。 PreloadSingleStep:每次执行时,先确保preloadmanager线程已经启动,然后尝试向显卡异步传输数据(WEBGL平台不支持这一特性)。异步上传的时间片和buffer大小默认分别为2ms和4MB的循环缓冲区。通过QualitySetting可以调整默认大小。然后查
inline函数 inline函数可以不受函数调用所带来的额外开销,编译器也会优化这些不含函数调用的代码,但是我们不能滥用Inline函数,如果程序中的每个函数都替换为inline函数那么生成的目标文件会急剧增加,当我们运行这个程序时会占用机器大量的内存,所以我们一般把本体很小的函数替换为Inline(一般10行以内)。 inline只是对编译器的申请,并不是强制执行,比方在class定义式内定义成员函数,如下所示 classPerson{ public: ... intage()const{returntheAge;}//animplicitinlinerequest:ageis ...//definedinaclassdefinition private: inttheAge; };复制 age()便被隐喻声明为inline. 而对于virtual函数,由于他需要在运行时决定调用哪个函数,所以即便是声明虚函数为Inline,编译器也会拒绝这个请求。 在构造函数和析构函数上使用Inline貌似可行,因为他们的函数体大多不长,甚至不含代码,但是这往往是个假象。 D