计算机中数值和字符串怎么用二进制表示?

作者:小牛呼噜噜 | http://xiaoniuhululu.com
计算机内功、JAVA底层、面试、职业成长相关资料等更多精彩文章在公众号「小牛呼噜噜」

大家好,我是呼噜噜。我们都知道现代计算机采用 0 和 1 组成的二进制,来表示所有的信息。那大家是不是有时候会有这些疑问:为什么计算机采用了二进制?二进制是如何表示计算机的相关信息的?比如数字、字符串、声音、图片、视频等等

进制

进位计算法是一种常见的计算方式,常见的有十进制,二进制,十六进制

  1. 十进制

十进制,都是以0-9这九个数字组成,不能以0开头, 逢十进一。
十进制是我们从小就潜移默化般学习的,我们大多数人拥有的手指或脚趾的数目就是10,天生让我们适合十进制为基础的数字系统

  1. 二进制

二进制,数字中只有 0 和 1,逢二进一

  1. 八进制

八进制,数字0-7,逢八进一

  1. 十六进制

十六进制,数字有 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F组成,逢十六进一。
其表示形式比较特殊,因为10~15不能用数字来展示,所以强制规定:10 用 A 表示、11 用 B 表示、12 用 C 表示、13 用 D 表示、14 用 E 表示、15用F表示

进制间的转换

  1. R进制 → 十进制按权展开

  1. 十进制 → R进制整数小数分开处理
  • 整数部分的转换方法是:“除基取余,上右下左”。即用要转换的十进制整数去除以基数R,将得到的余数作为结果数据中各位的数字,直到余数为0为止。上面的余数(先得到的余数) 作为右边低位上的数位,下面的余数作为左边高位上的数位。

  • 小数部分的转换方法是:“乘基取整,上左下右”。即用要转换的十进制小数去乘以基数R,将得到的乘积的整数部分作为结果数据中各位的数字,小数部分继续与基数R相乘。以此类推,直到某步乘积的小数部分为0或已得到希望的位数为止。最后,将上面的整数部分作为左边高位上的数位,下面的整数部分作为右边低位上的数位。

我们需要注意的是:在转换过程中,可能乘积的小数部分总得不到0,即转换得到希望的位数后还有余数,这种情况下得到的是近似值

  1. 二进制转八进制、十六进制

由于把二进制的三位看成一个整体就是八进制的数,二进制的四位也就是十六进制的数。通过这个规律,我们很容易地就能实现二进制与八进制、十六进制的相互转换。
整数部分低向高每3或4位数用一个等值八/十六进制数替换,不足时高位补0小数部分高向低每3或4位数用一个等值八或十六进制数替换,不足时低位补0

  1. 八进制、十六进制 转二进制

每一位数改成等值的3或4位二进制数,整数部分高位0省略;小数部分低位0省略

计算机为什么使用二进制?

我们从小更熟悉十进制的运算,0、1、2、3、4、5、6、7、8、9十个数字,逢十进一。但是计算机中使用二进制,只有0和1两个数字,逢二进一。

采用二进制的原因:

  1. 二进制在自然界中最容易被表现出来。自然界中二值系统非常多,电压的高低、水位的高低、门的开关、电流的有无等等都可以组成二值系统。
  2. 计算机使用二进制和现代计算机系统的硬件实现有关。制造二个稳定态的物理器件容易,使得组成计算机系统的逻辑电路通常只有两个状态,即开关的接通与断开。由于每位数据只有断开与接通两种状态,因此二进制的数据表达具有抗干扰能力强、可靠性高的优点
  3. 二进制非常适合逻辑运算,可方便地用逻辑电路实现 算术运算

机器数和真值

机器数

一个数在计算机中的二进制表示形式, 叫做这个数的机器数、机器码。
由于我们平时不仅使用的是正数,还有大量的负数,而计算机是无法识别符号"+","-", 所以计算机规定,用二进制数的最高位0表示正数,如果是1则表示负数。机器数是带符号的

如果十进制中的数 +3 ,计算机字长为8位,转换成二进制的机器数就是0000 0011。如果是-3,就是 10000011

真值

带符号位的机器数对应的真正数值是 机器数的真值,我们知道机器数的第一位是符号位, 比如1000 0011直接转换成十进制为131,但实际上最高位1 是负号,其真正的值为 [-3]

机器数的编码形式有哪些?

原码

原码就是符号位加上真值的绝对值, 即用最高位表示符号, 其余位表示值

比如如果是8位二进制:

  • [+1] = (0000 0001)原
  • [ -1] = (1000 0001)原

我们人类根据二进制的规则,可以一眼就明白原码代表的数字,方便了人类

面试的时候有一个经典的问题:8位二进制数原码的取值范围是
我们只需将除了最高位,用来表示符号,其他位都是1,即[1111 1111 , 0111 1111],换算成十进制:[-127 , 127]

那n位二进制数呢?

取值范围:

现在看起来都是那么美好,然而当我们将正负数相加时,遇到了问题:2个[+1]相减 ,其实就相当于[+1][-1] 相加,我们的预期是0
但计算机实际上计算时:(0000 0001)原+(1000 0001)原=(1000 0010)原 =[-2]

为了解决这个问题,反码就应运而生了

反码

反码主要是针对负数的,正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反

  • [+1] = (0000 0001)原 = (0000 0001)反
  • [-1] = (10000001)原 = (1111 1110)反

反码如果是表示的一个正数,那我们还是一眼就能知道他的数值,但如果是负数的反码时,我们就需要转换成原码才能看出它的真值。
如果最高位有进位出现,则要把它送回到最低位去相加(循环进位)的

[- 1] = (1000 0001)原 = (1111 1110)反

[+7] = (0000 0111)原 =(0000 0111)反

[-1] + [+7] = (1111 1110)反 +(0000 0111)反= (1 0000 0101)反 = (0000 0110)反 =[+ 6]

2个正数相减:[+1] - [+1] = [+1] + [-1] = (0000 0001)反 + (1111 1110)反 = (1111 1111)反 =(1000 0000)原 = [**-0**]
这样就完美实现了“正负相加等于0",但奇怪的是 ,这个[-0]是有符号的,这就要归因于 原码的设计之初,存在的问题,

  • (1000 0000)原=[- 0]
  • (0000 0000)原=[+0]

对的,你没看错,零竟然有2个,习惯计算机的万事万物一一对应,严谨认真的工程师们表示无法接受,得想办法去掉[-0],最后他们就发现了神奇的补码

补码

补码的规则:针对负数继续改进了思路:正数的补码就是其本身。负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后一位+1。即在反码的基础上最后一位+1

[+1] = (0000 0001)原 = (0000 0001)反 = (0000 0001)补
[-1] = (1000 0001)原 = (1111 1110)反 = (1111 1111)补

[+1] - [+1] = [+1] + [-1] = (0000 0001)补 + (1111 1111)补 = (1 0000 0000)补 = (0000 0000)补 = [0]
如果补码在补一位1的时候,发生最高位进位,会自动丢掉最高位。期间引用了计算机对符号位的自动处理,利用了最高位进位的自动丢弃实现了符号的自然处理。

(1000 0000)补 那现在表示多少?-128

  • (1000 0000)补 =-1 * 2^7 =[-128]
  • (1011)补 = -1 * 2^3 + 02^2 + 12^1 + 1*2^0 = -5
  • (0011)补 = 0 * 2^3 + 02^2 + 12^1 + 1*2^0 =3

如果是8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127],使用补码还能够多表示一个最低数

补码其实脱胎于 模运算系统
比如一天中的24小时是一个模运算系统,任意时刻的钟点数都是0到23间的一个整数,这有点类似24进制

  1. 今天的第24点,就是明天的0点;
  2. 今天的25点,就是明天的凌晨1点;
  3. 今天的-4点,就是昨天的20点,我们称20是-4对模24的补码,模就是容量、极值的意思

再举个例子:钟表上的12个刻度也是一个模运算系统。假定时钟现在指向10,要把指针只向6,有两种方法

  1. 倒拨4格:10 - 4 = 6
  2. 正拨8格:10 + 8 = 18 = 6 (mod 12)

所以模12系统中 -4 = 8 (mod 12),我们称8是-4对模12的补码

一个模运算系统中:一个负数可以用它的正补数(负数的补码)代替,一个负数的补码 = 模 - 该负数的绝对值

那我们之前公式 一个负数的补码 = 符号位不变, 其余各位取反, 最后一位+1,是怎么来的?

负数的原码 取反 再加1, 这只是方便大家记忆的手段,实际上它相当于加一个模256也就是2^8,为什么要拆,这是由于8位机,8位2进制数,至能表示0~255个数,一共256个数,所以它是表示不了256这个值的,只能是255+1。由于计算机系统里面不仅只有正数,还有负数呢,这个该怎么表示?
计算机大师就想到了,可以将256个数一分为二,规定最高位为符号位,最高位1开头的表示为负数,最高位0开头表示正数。我们这里需要注意一下,特殊的0,所以8位2进制数表示范围就变成了[-128,127],这个范围是不是很熟悉!

[-1] = (1000 0001)原 = (1111 1110)反 = (1111 1111)补,如果符号位参与计算,(1111 1111)补 的十进制 等于 255。255 + |-1|= 256,也就是模。补码本天成,妙手偶得之

小结一下:

  1. 补码不仅解决了[-0]的问题,更核心的是让计算机做减法运算,变成加法运算A - B = A + B的补码
  2. 使用补码,将减法变成加法运算,这样硬件上只需有加法器即可,不需要其他硬件,降低了电路的复杂度
  3. 使用补码,不浪费编码个数,存储空间利用率高
  4. 补码可以用n&0判断负数奇偶
  5. 所以计算机底层存储数据时使用的是二进制数字,但是计算机在存储一个数字时并不是直接存储该数字对应的二进制数字,而是存储该数字对应二进制数字的补码

定点数和浮点数

定点数

定点数的意思是:即约定机器中所有数据的小数点位置是固定不变的。通常将定点数据表示成纯小数或纯整数,为了将数表示成纯小数,通常把小数点固定在数值部分的最高位之前;而为了将数表示成纯整数,则把小数点固定在数值部分的最后面。
例如:十进制的 25.125

  • 整数部分:25使用二进制表示为:11001
  • 小数部分:0.125使用二进制表示为:.001
  • 所以合起来使用11001.001 表示十进制的25.125

本文的原码、反码、补码概念都是基于定点数

浮点数

定点数表示法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大或特别小的数,最终,绝大多数现代的计算机系统采纳了浮点数表达方式,这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa,尾数有时也称为有效数字,它实际上是有效数字的非正式说法),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数
例如:

  1. 352.47 = 3.5247 * 10的2次方
  2. 178.125转化为二进制为 10110010.001,又可表示为:1.0110010001 乘以 2的111次方(111是7的二进制表示)
  3. 123.45用十进制科学计数法可以表示为1.2345x10的2次方,其中1.2345为尾数,10为基数,2为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。

字符串编码

ASCII 码

在计算机中, 不仅数值可以用二进制表示,字符串也能用二进制表示。上世纪美国制定了一套字符编码,对英语字符与二进制位之间的关系,加上数字和一些特殊符号, 然后用 8 位的二进制,就能表示我们日常需要的所有字符了,这个就是我们常常说的ASCII 码

ASCII 码就好比一个字典,将二进制和字符一一对应。其中我们看几个典型的例子:

  1. 小写字母 a 在 ASCII 里面,十进制97,也就是二进制的 0 110 0001,而大写字母 A,十进制65,对应的二进制 0 100 0001
  2. 需要注意的是,里面的数字,比如数字1,二进制对应0000 0001 在ASCII 里面,表示的其实是字符"1",对应的二进制是0 011 0001
  3. 字符串 15 也不是用 0000 1111 这 8 位二进制来表示,而是变成两个字符 1 和 5 连续放在一起,也就是0 011 00010 011 0101,需要用两个 8 位二进制来表示 。所以**计算机储存数据时,二进制序列化会比直接存储文本能节省大量空间 **

EASCII:扩展的 ASCII

一开始美国编写ASCII表,英语用128个符号编码就够了,但随着计算机的普及,西欧国家不全是英语国家,有德语,法语等等

比如 字母上方有注音符号,它就无法用 ASCII 码表示。于是欧洲工程师就决定,利用字节中闲置的最高位编入新的符号。他们把 ASCII 扩充变成了 EASCII,这扩充的包括希腊字母、特殊的拉丁符号等。由于 ASCII 只占了 7 位,所以 EASCII 把第 8 位利用起来,仍然是一个字节来表示,这时表示的字符个数是 256。

Unicode

但 EASCII 并没有成功,西欧国家以及各个 PC 厂商各自定义出了好多不同的编码字符集,ISO-8859将西欧国家的编码一起包含进去。
但随着计算机来到中国,那些欧美国家把 现有的字典都用完,而且汉字有十多万个,所以急需新的"字典"。GB2312编码就出来了,使用两个字节表示一个汉字(汉字太多),所以理论上最多可以表示 256 x 256 = 65536 个符号。后来GBK编码 将古汉字等生僻字加进来。台湾地区又创造了BIG5编码,再后来GB18030对东南亚地区的文字,进行了统一。简单了解下这些编码,就不具体展开了

再后来计算机全球普及,各个国家地区的文字编码太多太乱,Unicode编码的出现,为了统一全世界的所有字符。Unicode 是一个很大的集合,现在的规模可以容纳100多万个符号。

由于Unicode 只是一个字符集(Charset),它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储,也就是字符编码(Character Encoding),这就导致计算机无法区别 Unicode 和 ASCII ,比如三个字节表示一个符号,而不是分别表示三个符号呢?

随着互联网的崛起,UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。UTF-8 它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。Unicode 字符集中的大部分汉字,如果用 UTF-8 编码的话,是占 3 个字节的

下面我们看看UTF-8是如何兼容Unicode的:
UTF-8编码致力于统一世界上所有的字符集,所以它的设计上既向下兼容ASCII码的编码方式,同时又考虑了可拓展性,规则如下:
1)对于单字节的符号:字节的第一位设为0,后面7位为这个符号的 Unicode 码。与 ASCII 编码规则相同;
2)对于n字节的符号(n > 1):第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

Unicode UTF-8 byte 数
0000~007F 0XXX XXXX 1
0080~07FF 110X XXXX 10XX XXXX 2
0800~FFFF 1110 XXXX 10XX XXXX 10XX XXXX 3
1 0000~1F FFFF 1111 0XXX 10XX XXXX 10XX XXXX 10XX XXXX 4

我们可以发现,UTF-8 编码的第一位如果是 0,则只有一个字节,跟 ASCII 编码完全一样,所以兼容了。如果是 110 开头,则是两个字节,以此类推如上表所示。所以开头几位的值,是编码本身,同时又是判断后续还有几个字节数的推码(通过推码才能判断这个字节之后还有几个字节共同参与一个字符的表示)

乱码的来源

编码是把数据从一种形式转换为另外一种形式的过程,而解码则是编码的逆向过程。编码是一种格式,解码是另一种格式,当然会出问题。下面我们举个例子,来看看这个问题:

  1. 创建hello.txt文件,用Notepad++打开编辑,以 UTF-8 格式写入你好
  2. 然后我们改变Notepad++formaat格式,改为GB2312,然后你好就变成了浣犲ソ

在UTF-8 字典中,你好两个字的16进制编码分别是E4BDA0E5A5BD
在GB2312字典中,浣犲ソ三个字的16进制编码分别是 E4BDA0E5A5BD

由于在UTF-8 编码汉字是 3 个字节,在GB2312编码汉字却是2个字节,计算机用GB2312去解析UTF-8,硬生生的把3个字节以每2个字节为一组去解码,所以才会有出现这种乱码。当我们知道乱码出现的原因,如何解决就变的非常简单了


参考资料:
《编码:隐匿在计算机软硬件背后的语言》
《深入理解计算机系统 第三版》
《计算机组成原理》
《深入计算机组成原理》
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
http://www.zhihu.com/question/20159860
http://blog.csdn.net/f919976711/article/details/116714860


本篇文章到这里就结束啦,很感谢靓仔你能看到最后,如果觉得文章对你有帮助,别忘记关注我!
计算机内功、JAVA源码、职业成长、项目实战、面试相关资料等更多精彩文章在公众号「小牛呼噜噜」

本文转载于网络 如有侵权请联系删除

相关文章

  • 《JavaScript 模式》读书笔记(6)— 代码复用模式2「建议收藏」

    大家好,又见面了,我是你们的朋友全栈君。  上一篇讲了最简单的代码复用模式,也是最基础的,我们普遍知道的继承模式,但是这种继承模式却有不少缺点,我们下面再看看其它可以实现继承的模式。四、类式继承模式#2——借用构造函数本模式解决了从子构造函数到父构造函数的参数传递问题。本模式借用了父构造函数,它传递子对象以绑定到this,并且还转发任意参数。functionChild(a,c,b,d){ parent.apply(this,arguments); }复制  在这种方式中,只能继承在父构造函数中添加到this的属性。同时,并不能继承那些已添加到原型中的成员。  使用该借用构造函数模式时,子对象获得了继承成员的副本,这与类式继承模式#1中,仅获取引用的方式是不同的。下面的例子演示了其差异://父构造函数 functionArticle(){ this.tags=['js','css']; } vararticle=newArticle(); //blog文章对象继承了article对象 //viatheclassicalpattern#1 func

  • Shell脚本个例

    1、从列表文件中读取用户名,批量自动创建多个用户并设置密码。 创建用户列表,用户密码 #viuserlist #vipasswd 编写useradd脚本,代码如下 #viuseradd.sh#!/bin/sh //执行器请添加700权限 foruserin`cat/root/userlist` do useradd$user echo"123456"|passwd--stdin$user//此处暂时设置初始密码123456 echo"passwordload" done chpasswd</root/passwd//调用chpasswd修改文本中密码 pwconv cat/root/passwd复制执行效果如下: 2、从列表文件中读取主机IP地址,逐个测试是否在线。 1、创建主机IP地址列表文件 #viipaddrs 2、编写测试脚本 #vifping.sh#!/bin/sh HLIST=$(cat/root/ipaddrs) forIPin$HLIST do ping-c3-i0.2-W3$IP&>/dev/null if[

  • 【管中窥豹集】你真的了解“随机”这两个字意味着什么吗?

    |原创作者|Jerry“举管而望,观一斑可思全豹”--管中窥豹集·杰瑞IC验证今日聊“随机”。有哥们儿说:“这东西太熟悉了不用聊!我们跑仿真的时候,每天都在随机测试嘛”。好的,Jerry给你讲一个小明的验证故事,看看如果给随机“换了一身衣服”,你还是不是真的认识它。小明有一天接到了这样一个验证需求:他的待验证对象是一个公共的RTL模块,且这个公共RTL模块带了很多parameter,正因为是公共的模块所以它的parameter没有固定值,而是依据未来不同系统应用传入不同的parameter值,但是小明的任务是完整验证这个公共模块,他就需要考虑例化时传入不同parameter的情况。请注意这个验证需求的特殊点:例化时传入不同的parameter代表着完全不同的RTL!即假如有500种parameter的组合,小明相当于需要验证500个完全不同的RTL!聪明的小明马上制订了验证策略:1.不论如何变化parameter一定要保证验证平台和绝大部分验证case可以复用,这样只需要改变parameter就可以完成不同RTL的快速回归测试。2.parameter以宏的方式传入,500种parame

  • SAAS微服务脚手架推荐

    基于SpringCloud(Hoxton.SR3)+SpringBoot(2.2.6.RELEASE)的SaaS微服务脚手架,具有统一授权、认证后台管理系统,其中包含具备用户管理、资源权限管理、网关API、分布式事务、大文件断点分片续传等多个模块,支持多业务系统并行开发,可以作为后端服务的开发脚手架。代码简洁,架构清晰,适合学习和直接项目中使用。核心技术采用Nacos、Fegin、Ribbon、Zuul、Hystrix、JWTToken、Mybatis、SpringBoot、Redis、RibbitMQ等主要框架和中间件。模式介绍本项目可以通过配置,轻松切换项目的租户模式。部署方面,可以采用以下几种方式:IDEA启动jar部署docker部署k8s部署jenkins自动化部署功能点介绍:服务注册&发现与调用: 基于Nacos来实现的服务注册与发现,使用使用Feign来实现服务互调,可以做到使用HTTP请求远程调用时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。服务鉴权: 通过JWT的方式来加强服务之间调度的权限验证,保证内部服务的

  • 这 10 道 Spring Boot 常见面试题你需要了解下

    1.什么是SpringBoot?多年来,随着新功能的增加,spring变得越来越复杂。只需访问https://spring.io/projects页面,我们就会看到可以在我们的应用程序中使用的所有Spring项目的不同功能。如果必须启动一个新的Spring项目,我们必须添加构建路径或添加Maven依赖关系,配置应用程序服务器,添加spring配置。因此,开始一个新的spring项目需要很多努力,因为我们现在必须从头开始做所有事情。SpringBoot是解决这个问题的方法。SpringBoot已经建立在现有spring框架之上。使用spring启动,我们避免了之前我们必须做的所有样板代码和配置。因此,SpringBoot可以帮助我们以最少的工作量,更加健壮地使用现有的Spring功能。2.SpringBoot有哪些优点?减少开发,测试时间和努力。使用JavaConfig有助于避免使用XML。避免大量的Maven导入和各种版本冲突。提供意见发展方法。通过提供默认值快速开始开发。没有单独的Web服务器需要。这意味着你不再需要启动Tomcat,Glassfish或其他任何东西。需要更少的配置因

  • 2019年元宵节海报psd源文件合集

    马上元宵节了,大家肯定又会到处找素材找模板,近期整理了一些元宵节PSD模板,分享给大家。后台回复“元宵节快乐” 即可获取素材包时刻提醒自己不抱怨,多实践,终达成功彼岸!我的座右铭:不能领跑也绝不放弃!

  • Mac 电脑如何卸载 node

    版权声明:本文为原创文章发布于公众号:Modeng,你可以随意转载但请务必注明出处!!! https://blog.csdn.net/qq_32135281/article/details/81585591 因为刚入手「Mac」很多淫技还不懂,在一次使用npminstall的时候安装出错,提示为npm与node的版本有问题,所以就想着卸载重新装一个版本。但是因为刚使用「Mac」所以为是蒙逼的不知道怎么去卸载,于是就去网上查阅了一番。后面发现有些办法是删除不掉node的,所以避免下次在出现这样的情况,把这次删除node的方法纪录下来,以便以后使用。一在终端依次输入以下命令1sudo npm uninstall npm -g 2 3sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.* 4 5sudo rm -rf /usr/local/include/node /Users/$USER/.npm 6 7sudo rm /usr/local/bin/node

  • 观点 | 深度学习:简单而有局限性的求解方式

    选自KerasBlog作者:FrancoisChollet机器之心编译参与:路雪、李泽南在人工智能,特别是深度学习破解了一个又一个难题,在很多任务上达到超过人类认知水平的今天,我们距离真正的人工智能仍很遥远。本文摘自作者出版的新书《DeepLearningwithPython》第九章第二节,其中简要介绍了深度学习的原理、强大能力、以及无处不在的局限性。深度学习:几何视角关于深度学习最令人吃惊的事实莫过于它的简单程度。10年前,没人想到我们会使用简单的梯度下降参数模型在机器认知领域取得如此卓越的成绩。现在,只需要在足够多的样本上用梯度下降方法训练出足够大的参数模型即可。正如费曼曾经说的:「宇宙并不复杂,它只是由若干个宇宙组成而已。」在深度学习领域,一切都只是向量,即一切都是几何空间中的点。模型输入(可以是文本、图像等)和目标都要首先进行向量化,即转换成原始输入向量空间和目标向量空间。深度学习模型的每一层对其中的数据进行简单的几何变换。多个层就形成一个非常复杂的几何变换,可以被拆解成多个简单的几何变换。这一复杂的几何变换尝试在输入空间和目标空间之间建立映射关系,一次对应一个点。该变换通过各

  • 罗兰贝格:跨越转型 中国证券业谋定而动

  • 深入理解计算机系统(4.1)------Y86指令集体系结构

      本章我们将进入处理器体系结构介绍的神秘海洋中,我们熟悉的手机,电脑等设备的核心硬件都离不开处理器。处理器可以称的上是人类创造的最复杂的系统之一,一块手指大小的硅片,可以容纳一个完整的高性能处理器、大的高速缓存,以及用来连接外部的逻辑电路。而且由于摩尔定律,从性能上讲,今天一块芯片上的处理器,已经使得三十年前比房间那么大的超级计算机都相形见绌了。  那么可能有人会问,我们软件开发者,永远都不会自己去设计处理器,那我们为什么要学习处理器的实现?  ①、首先处理器的设计是非常有趣而且重要的,处理器设计包括很多好的工程实践原理,它需要完成复杂的任务,而结构又要尽可能的简单和规则,我们去了解事物是怎样工作的有其内在的价值。  ②、处理器是整个计算机能正常工作的重要组成部分,理解处理器如何工作能帮助我们理解整个计算机如何工作。  ③、虽然我们不用去设计处理器,但是我们工作的产出很多都是在包含处理器的硬件系统上运行的,了解它能让我们工作更有效率。  我们知道计算机系统底层硬件只识别机器语言,而处理器就是用来执行一系列指令,每条指令执行某个简单的操作。比如两个数相加,汇编指令ADD会被编码为一个或

  • WordPress如何快速获取文章别名

    WordPress文章别名是对固定链接有着事关重要的作用,因为非常多的WordPress站长喜欢将文章别名用作URL,所以这时候文章别名就是判断和获取一篇文章的重要关键,但是不排除一些WordPress用户使用ID作为固定链接。而且利用文章别名做URL有一定的SEO优势,能够增强关键词的关联性,比起阅读意义的文章ID来说显得更有展现优势,同时有时候可能也需要通过文章别名做一些别的数据展现,甚至有时候就需要单独用到文章别名。今天子凡在更新一个插件小功能的时候,由于对接小程序我们并没有完全使用文章ID,而是使用的文章别名,为了统一百度小程序的URL规则适配,那么就需要单独的用到文章的别名,下面就分享一下WordPress如何快速获取文章别名的两个方法。1 2 3//WordPress获取文章别名 $pid=0; $post_slug=get_post_field('post_name',get_post($pid));这种方法比较准确,能够指定文章ID,并且如果在循环中还可以不用指定ID,当然如果直接调用显得更方便的就是下面这种方式。1 2 3//WordPress获取

  • Java学习笔记 -IO流2

    缓冲流&转换流 示例1-BufferedReader (1)知识点: BufferedReader:带有缓冲区的的字符输入流 使用这个流的时候不需要自定义char数组或者byte数组,自带缓冲 构造方法:BufferedReader(Readerin)缓冲流的使用需要传递参数:字符流,字节流不行 概念:包装流&节点流 方法:readLine()读取一行,会丢弃换行符,如果读取到文件结尾则返回null (2)程序: importjava.io.BufferedReader; importjava.io.FileNotFoundException; importjava.io.FileReader; importjava.io.IOException; publicclassBufferedReaderTest01{ publicstaticvoidmain(String[]args){ BufferedReaderbr=null; try{ //当一个流的构造方法需要一个流的时候:这个流称为节点流 //外部负责包装的流:包装流或处理流 FileRea

  • Takin实践笔记

    先来看官网:https://news.shulie.io/ https://docs.shulie.io/docs/opensource/opensource-1d40ib39m90bu 接下来我们根据文档一步步的操作: 简介:Takin是基于Java的开源系统,可以在无业务代码侵入的情况下,嵌入到各个应用程序节点,实现生产环境的全链路性能测试,适用于复杂的微服务架构系统。 GitHub开源地址如下:https://github.com/shulieTech/Takin 术语表 业务活动 业务活动指的就是单接口的链路。在压测场景里可以对业务活动发起压测。 影子库表 影子表:原始表的副本。影子表前缀通常以PT_开头,作用是存储压测生产的数据,目的是做数据隔离确保真实业务数据的安全。影子库:同影子表,只是以库的维度隔离。方案选择:①影子库方案:不清楚表的调用情况,就从原始库copy一份,不用去梳理库里表的详细情况②影子表方案:清楚表的调用情况,那就在同库里建影子表 白名单 在客户端应用里,将对外调用的接口加入到白名单,表示允许压测流量通过。 挡板 顾名思义,阻止/限制作用。挡板可以将请求拦

  • spring aop 之annotation

    1.CutPointInterface publicinterfaceCutPointInterface{ voidmethod(); }复制 2.CutPointClass  @Component publicclassCutPointClassimplementsCutPointInterface{ @Override publicvoidmethod(){ //TODOAuto-generatedmethodstub System.out.println("切点类"); } }复制 3.AspectClass  @Aspect publicclassAspectClass{ @Pointcut("execution(*com.lzp.annotationAop.CutPointInterface.method(..))") publicvoidmethod(){ } @Before("method()") publicvoidbefore(){ System.out.println("之前"); } @After("method()") p

  • ESP8266 NOOS SDK libat.a Functions

    at_baseCmd.ocustom_infoat_baseCmd.oat_exeCmdNullat_baseCmd.oat_setupCmdEat_baseCmd.oat_exeCmdRstat_baseCmd.oat_set_custom_infoat_baseCmd.oat_exeCmdGmrat_baseCmd.oat_setupCmdIprat_baseCmd.oat_execCmdRestoreat_baseCmd.oat_setupCmdGslpat_baseCmd.oat_setupCmdSleepat_baseCmd.oat_queryCmdSleepat_baseCmd.oat_setupCmdWakeupGPIOat_baseCmd.oat_setupCmdRFPowerat_baseCmd.oat_setupCmdRFVddat_baseCmd.oat_execCmdRFVddat_baseCmd.oat_queryCmdRFVddat_baseCmd.oat_get_rf_auto_trace_from_flashat_baseCmd.oat_queryCmd

  • 测试

    北木商城购物流程一、注册及登录1、新会员注册:用户可以点击首页顶端或首页登录注册“免费注册”进入注册页面后选择使用邮箱地址或者手机号码注册,然后输入密码、确认密码及验证码,勾选我已阅读并同意《北木诚服务协议》,按照提示完成注册。2、会员登陆:用户可以点击首页顶端或首页右上栏“登录”进入登录页面后,登陆账号、密码进行登陆。3、忘记密码:对于忘记密码的会员,我们提供了找回密码的功能,请在找回密码的页面中输入您的用户名、注册时电子邮箱或已验证的手机号,系统将帮助您找回密码。二、查找商品1、您可以通过在首页输入关键字的方法来搜索您想要购买的商品。2、您还可以通过分类导航栏来找到您想要购买的商品分类,根据分类找到您的商品。三、放入购物车1、挑选商品后,在商品详细页面点击“购买”按钮,将商品放入购物车中。2、在购物车中,系统默认每件商品的订购数量为一件,如果您想购买多件商品,可修改购买数量。3、在购物车中,您可以将商品加入收藏夹,或是选择删除。4、在购物车中,您可以直接查看到商品的名称、价格、优惠活动。温馨提示:1、商品价格会不定期调整,最终价格以您提交订单后订单中的价格为准。2、优惠政策、配送时

  • [CTSC2010]珠宝商

    https://www.luogu.org/problemnew/show/P4218 题解 树上路径问题可以想到用点分治。 考虑固定一分治点,然后算所有跨过这个点的所有路径的答案和。 假定我们分治重心为\(x\),那么一条合法的路径可以表示为\(u->x\x->v\)。 然后我们还要考虑两条路径拼接的情况。 那么考虑对于模板串\(m\)的一个分割点,\(u->x\)的路径一定是\(m\)的这个分割点前的串的后缀,\(x->v\)一定是后面的串的前缀。 后缀这个东西相当于是\(parent\)树上的子树,前缀的话得对反串建\(parent\)树。 所以我们每次的操作就是在当前串的前面加一个字母。 这个怎么做? 考虑这个操作其实就是在\(parent\)树上走,所以把\(parent\)树处理一下就好了。 然后在\(parent\)树上打完标记之后,最后要把标记全部下放到代表模板串前缀的点,然后算贡献。 但是这样每次后续都需要\(O(m)\)的处理,考虑到如果对于一个小的子树都要\(O(m)\)的做非常浪费,所以我们就设一个阈值,当块小的时候暴力做。 然后一朵菊花

  • 谈谈自己对rest和RPC的理解

    一、什么是rest rest是一种架构风格,restful是遵循这种架构风格的应用程序或者设计。rest这种架构风格是美国一个博士在他的博士论文中提出来的,皆在于解决随着互联网的快速发展,传统的软件已经无法满足在这个时代背景下人们需求。在这个新的时代下,在这个万物互联的时代下,网络和软件这两个曾经单独存在的领域,已经无法在单独存在了,两者之间的交互和融合已经势在必行。rest架构风格就是在这样一个背景下被提出来的,他强调组件交互的可伸缩性、接口的通用性、组件的独立部署、以及用来减少交互延迟、增强安全性。 在以前,谈到互联网,想到的就是网站,网站成了互联网的代名词。但是在现在,互联网这一个伟大的发明正逐渐释放出他真正的潜力,不仅仅作用于浏览网站。但是不管怎么发展,本质上都是一个客户端和一个服务端的交互,这个本质我相信是改变不了的。客户端和服务端交互少不了http协议,这是一个标准,但这个标准有局限性,那就是他只定义了在客户端发出请求到服务端接受请求这一过程和服务端返回响应和客户端接受响应这一过程。(未完待续)

  • 统计学习方法 李航---第9章 EM算法及其推广

    第9章EM算法及其推广 EM算法是一种迭代算法,用于含有隐变量(hiddenvariable)的概率模型参数的极大似然估计,或极大后验概率估计。EM算法的每次迭代由两步组成:E步,求期望(expectation);M步,求极大(maximization),所以这一算法称为期望极大算法(expectationmaximization algorithm),简称EM算法。 9.1 EM算法的引入   一般地,用Y表示观测随机变量的数据,Z表示隐随机变量的数据。Y和Z连在一起称为完全数据(complete-data),观测数据Y又称为不完全数据(incomplete-data)。假设给定观测数据Y,其概率分布是P(Y|theta),其中theta是需要估计的模型参数,那么不完全数据Y的似然函数是P(Y|theta),对数似然函数L(theta)=logP(Y|theta);假设Y和Z的联合概率分布是P(Y,Z}句,那么完全数据的对数似然函数是logP(Y,Z |theta)。 观测数据的似然函数为 EM算法通过迭代求L(theta)=log

  • ubuntu16 升级 tmux 2.9

    #首先需要安装这个库 #http://libevent.org/ wgethttps://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz tar-zxvflibevent-2.1.8-stable.tar.gz cdlibevent-2.1.8-stable bashconfigure make-j4 sudomakeinstall #链接 sudoln-s/usr/local/lib/libevent-2.1.so.6/lib64/libevent-2.1.so.6 sudoln-s/usr/local/lib/libevent-2.1.so.6/lib/libevent-2.1.so.6 sudoaptinstallncurses-dev #然后下载tmux #https://github.com/tmux/tmux/wiki cd wgethttps://github.com/tmux/tmux/releases/download/

  • 傅里叶变换(1)

    概述   此系列文章仍然是我自己的带反思回忆元素和学习笔记性质的随笔而非科普向的文章。所以想借此篇来学习傅里叶变换的朋友可以出门左拐了。   傅里叶变换是贯穿整个电信专业的一个重要内容,在我没学会傅里叶变换之前我拿到一本教科书看到目录中出现傅里叶三个字就开始头疼并对该门课产生恐惧。   傅里叶变换是一个用途很广的数学操作,光我接触到的就有数字信号处理,电路设计和图像处理等实际工程中。建立一个首先的印象是,傅里叶变换是一个将时域的结果转化为频域的结果的过程,比如将经典的时间-幅度函数图象转化为频率-幅度图象。这是一个令人耳目一新的操作,领悟之后有豁然开朗甚至醍醐灌顶的效果,毕竟这是一种全新的思维方式。初学时我们通过时域图象可以了解一个波形信号,但在另外很多的时候,通过频域图象来认识和描述一组信号的波形会更加直观和方便。   这里要插一个话题是频谱图这个东西并不是本科时才开始接触的,而是自幼就看到过,这就是音频频谱图,常出现在音乐软件的UI和功放机面板上。当时我就很奇怪这些竖条具体是什么意思,但我很确定的是,这些竖条的高度和声音的响度成正相关。     这些竖条横轴是频率,大概

相关推荐

推荐阅读