文档库 最新最全的文档下载
当前位置:文档库 › 无符号数的识别

无符号数的识别

无符号数的识别
无符号数的识别

无符号数的词法分析程序

一、实验目的和要求

(1)初步掌握编译原理的实验的技能;

(2)验证所学理论、巩固所学知识并加深理解。

二、实验内容和原理

内容:掌握词法分析的基本思想,并用高级语言编写无符号数(包括整数和实数)的词法分析程序。

要求:从键盘中输入一字符串(包括字母、数字等),编写程序识别出其中的无符号数。

无符号数的文法规则课定义如下:

<无符号数>

<无符号实数>|<无符号整数>

<无符号实数> <无符号整数>.<数字串>[E<比例因子>]

<比例因子> <有符号整数>

<有符号整数> [+|-]<无符号整数>

<无符号整数> <数字串>

<数字串> <数字>{<数字>}

<数字> 0 1 2 3 4 5 6 7 8 9

本实验中我利用了状态转化图的思想,下面是试验中用到构造的状态转化图:

描述状态机的代码格式如下:

int state = S0 ;

while(1)

{

Switch(state)

{

case S0 :

if(T0转移条件满足) {状态转移到满足T0的次态;操作;}

if(T1转移条件满足) {状态转移到满足T1的次态;操作;}

if(T2转移条件满足) {状态转移到满足T2的次态;操作;}

Break ;

case S1 :

//插入S1状态下的操作;

break ;

}

}

实验代码:

//本程序主要实现实数的识别

import java.io.BufferedReader ;

import java.io.IOException ;

import java.io.InputStreamReader ;

public class RealNumberIdentified {

/*---------------------------------成员变量的定义---------------------------------------*/

private final int S_0 = 0 ;

private final int S_1 = 1 ;

private final int S_2 = 2 ;

private final int S_3 = 3 ;

private final int S_4 = 4 ;

private final int S_5 = 5 ;

private final int S_6 = 6 ;

private final int S_7 = 7 ;

private char originNumber[ ] ; //用来记录原始的数字串

private String resultNumber = new String( ) ;

private int realnumberAmount = 0 ; //用来记录识别出的实数的个数

private int realnumberFlag = 0 ; //用于标识该实数是正数还是负数

private int eFlag = 0 ; //用来标识该实数是不是指数实数

private int pointFlag = 0 ; //用来标识该实数是否是小数

private int basePlusMinus = 1 ; //用来标识底数的符号

private int count = 0 ; //用来记录已经识别数字串的位数

private int currentState = S_0 ; //用来记录当前所处于的状

/*---------------------------------------------------------------------------------- -----*/

/*-------------------------该方法用来初始化一些参数------------------------------------*/

private void init( )

{

resultNumber = new String( ) ;

basePlusMinus = 1 ;

eFlag = 0 ;

pointFlag = 0 ;

}

/*----------------------------------------------------------------------------------------*/

/*---------------------init( )方法用于去除实数串开始和结尾的无效的空格

----------------*/

private void initOriginNumber( String str )

{

str = str.trim( ) ;

str += '#' ;

originNumber = str.toCharArray( ) ;

}

/*-----------------------------------------------------------------------------------------*/ /*---------------------------printResult()方法用来输出识别的结果

------------------------*/

private void printResult( )

{

if( realnumberFlag == 0 )

System.out.println( "\n识别结束,您所输入的字符串中不包含任何实数!" ) ;

else

{

realnumberAmount ++ ;

if( realnumberAmount == 1 )

System.out.println( "\n识别结束,您所输入的字符串中所包含的实数如下:" ) ;

if( resultNumber.length( ) != 0 )

{

if( eFlag == 1 )

if( basePlusMinus == 1 )

System.out.println( "正指数实数:" +

Double.parseDouble( resultNumber ) ) ;

else

System.out.println( "负指数实数:" +

Double.parseDouble( resultNumber ) ) ;

else

if( pointFlag == 1 )

System.out.println( " 小数:" + Double.parseDouble( resultNumber ) ) ;

else

{

if( basePlusMinus == 1 )

System.out.println( " 正整数:" + Long.parseLong( resultNumber ) ) ;

else

System.out.println( " 负整数:" + Long.parseLong( resultNumber ) ) ;

}

}

}

}

/*-----------------------------------------------------------------------------------------*/

/*--------------------------------识别该实数串的过程-------------------------------------*/

private void identifiedProcess( String str )

{

initOriginNumber( str ) ;

while( count < originNumber.length )

{

switch( currentState )

{

case S_0 : {

if( originNumber[ count ] == '+' )

{

resultNumber = resultNumber + originNumber[ count ] ;

currentState = S_1 ;

}

else

{

if( originNumber[ count ] == '-' )

{

resultNumber = resultNumber + originNumber[ count ] ;

basePlusMinus = 0 ;

currentState = S_1 ;

}

else

if( originNumber[ count ] >=48 && originNumber[ count ] <=57 )

{

resultNumber = resultNumber + originNumber[ count ] ;

realnumberFlag = 1 ;

currentState = S_2 ;

}

else

{

currentState = S_0 ;

}

}

count ++ ;

break ;

}

case S_1 : {

if( originNumber[ count ] >=48 && originNumber[ count ] <=57 )

{

resultNumber = resultNumber + originNumber[ count ] ;

realnumberFlag = 1 ;

currentState = S_2 ;

}

else

{

resultNumber = resultNumber.substring( 0 , resultNumber.length( ) - 1 ) ;

currentState = S_0 ;

}

count ++ ;

break ;

}

case S_2 : {

if( originNumber[ count ] == '.' )

{

resultNumber = resultNumber + originNumber[ count ] ;

currentState = S_3 ;

}

else

if( originNumber[ count ] >=48 && originNumber[ count ]

<=57 )

{

resultNumber = resultNumber +

originNumber[ count ] ;

currentState = S_2 ;

}

else

if( originNumber[ count ] == 'E' || originNumber[ count ] == 'e' )

{

resultNumber = resultNumber + originNumber[ count ] ;

currentState = S_5 ;

}

else

{

if( originNumber[ count ] == '+' || originNumber[ count ] == '-' )

count -- ;

printResult( ) ;

init( ) ;

currentState = S_0 ;

}

count ++ ;

break ;

}

case S_3 :{

if( originNumber[ count ] >=48 && originNumber[ count ] <=57 )

{

resultNumber = resultNumber + originNumber[ count ] ;

pointFlag = 1 ;

currentState = S_4 ;

}

else

{

resultNumber = resultNumber.substring( 0 , resultNumber.length( ) - 1 ) ;

printResult( ) ;

init( ) ;

currentState = S_0 ;

}

count ++ ;

break ;

}

case S_4 : {

if( originNumber[ count ] >=48 && originNumber[ count ] <=57 )

{

resultNumber = resultNumber + originNumber[ count ] ;

currentState = S_4 ;

}

else

{

if( originNumber[ count ] == 'E' || originNumber[ count ] == 'e' )

{

resultNumber = resultNumber + originNumber[ count ] ;

currentState = S_5 ;

}

else

{

if( originNumber[ count ] == '+' || originNumber[ count ] == '-' )

count -- ;

printResult( ) ;

init( ) ;

currentState = S_0 ;

}

}

count ++ ;

break ;

}

case S_5 : {

if( originNumber[ count ] == '+' )

{

resultNumber = resultNumber + originNumber[ count ] ;

currentState = S_6 ;

}

else

if( originNumber[ count ] == '-' )

{

resultNumber = resultNumber +

originNumber[ count ] ;

currentState = S_6 ;

}

else

if( originNumber[ count ] >= 49 &&

originNumber[ count ] <= 57 )

{

resultNumber = resultNumber + originNumber[ count ] ;

eFlag = 1 ;

currentState = S_7 ;

}

else

{

resultNumber = resultNumber.substring( 0 , resultNumber.length( ) - 1 ) ;

printResult( ) ;

init( ) ;

currentState = S_0 ;

count -- ;

}

count ++ ;

break ;

}

case S_6 : {

if( originNumber[ count ] >= 49 && originNumber[ count ] <= 57 )

{

resultNumber = resultNumber + originNumber[ count ] ;

eFlag = 1 ;

currentState = S_7 ;

}

else

{

resultNumber = resultNumber.substring( 0 , resultNumber.length( ) - 2 ) ;

printResult( ) ;

init( ) ;

currentState = S_0 ;

count -= 2 ;

}

count ++ ;

break ;

}

case S_7 : {

if( originNumber[ count ] >= 48 && originNumber[ count ] <= 57 )

{

resultNumber = resultNumber + originNumber[ count ] ;

currentState = S_7 ;

}

else

{

if( originNumber[ count ] == '+' || originNumber[ count ] == '-' )

count -- ;

printResult( ) ;

init( ) ;

currentState = S_0 ;

}

count ++ ;

break ;

}

}

}

printResult( ) ;

}

/*------------------------------------------------------------------------------------------*/

/*----------------------------------------主方法-------------------------------------------*/

public static void main(String[ ] args) throws IOException {

System.out.print( "请输入欲识别的实数:" ) ;

BufferedReader buf = new BufferedReader( new

InputStreamReader( System.in ) ) ;

new RealNumberIdentified( ).identifiedProcess( buf.readLine( ) ) ;

}

/*------------------------------------------------------------------------------------------*/

}

三、实验结果

四、讨论、分析和心得

在本次试验我并没有采用课本中提供的算法,而是将在课本中学到的状态转化图和自动机的理论加以利用以基本实现本次实验的要求。

将上面自动机的思想配上前面我画的状态转化图可以明白,初始设置currentStack位于S0处,每识别一个完整的数字会将currentStack重新赋值为S0,有事也有读头往回的情况发生例如:9E1.1,应该读成数字9和1.1,但是在识别过程中会一直识别到’.’才会发现这个数不是一个指数实数,这样一直读下去即可将整个符号串中数字识别出来。

数学符号

数量符号: i,a,x,e,π 运算符号: 并集(∪),交集(∩),根号(√ ̄),对数(log,lg,ln,lb),比(:),绝对值符号| |,微分(d),积分(∫),闭合曲面(曲线)积分(∮) 关系符号: “≥”是大于或等于符号(也可写作“≮”,即不小于),“≤”是小于或等于符号(也可写作“≯”,即不大于),“→ ”表示变量变化的趋势,“∽”是相似符号,“≌”是全等号,“∥”是平行符号,“?”是垂直符号,“∝”是正比例符号(表示反比例时可以利用倒数关系),“∈”是属于符号,“?”是包含于符号,“?”是包含符号,“|”表示“能整除”(例如a|b 表示“a能整除b”,而||b表示r是a恰能整除b的最大幂次),x,y等任何字母都可以代表未知数。 省略符号: 三角形(△),直角三角形(Rt△),正弦(sin)(见三角函数),双曲正弦函数(sinh),x的函数(f(x)),极限(lim),角(∠),∵因为∴所以总和,连加:∑,求积,连乘:∏,从n个元素中取出r个元素 所有不同的组合数(n元素的总个数;r参与选择的元素个数),幂 排列组合符号 C 组合数 A (或P) 排列数 n 元素的总个数 r 参与选择的元素个数 ! 阶乘,如5!=5×4×3×2×1=120,规定0!=1 !! 半阶乘(又称双阶乘),例如7!!=7×5×3×1=105,10!!=10×8×6×4×2=3840 离散数学符号 ?全称量词 ?存在量词 ├断定符(公式在L中可证) ╞满足符(公式在E上有效,公式在E上可满足) ﹁命题的“非”运算,如命题的否定为﹁p ∧命题的“合取”(“与”)运算 ∨命题的“析取”(“或”,“可兼或”)运算 → 命题的“条件”运算 ? 命题的“双条件”运算的 p<=>q 命题p与q的等价关系 p=>q 命题p与q的蕴涵关系(p是q的充分条件,q是p的必要条件) A* 公式A的对偶公式,或表示A的数论倒数(此时亦可写为) wff 合式公式 iff 当且仅当 ↑ 命题的“与非” 运算(“与非门” ) ↓ 命题的“或非”运算(“或非门” ) □模态词“必然” ◇模态词“可能” ?空集

C语言有符号数与无符号数之间的转换

C语言有符号数与无符号数之间的转换 无符号数:不存在正负之分,所有位都用来表示数的本身。 有符号数:最高位用来表示数的正负,最高位为1则表示负数,最高位为0则表示正数。 1.无符号数--->有符号数 看无符号数的最高位是否为1,如果不为1(为0),则有符号数就直接等于无符号数;如果无符号数的最高位为1,则将无符号数取补码,得到的数就是有符号数。 以unsigned char 和char为例子: 1.1将无符号数2转为有符号数 2的原码是:0000 0010,可知最高位不为1,因此转为有符号数之后也是2。 程序: 1 #include 2 3int main(void) 4{ 5 unsigned char i = 2; 6 7 printf("%d/n",(char)i); 8 9return0;10} 运行结果: 1.2将无符号数130转为有符号数 130的原码是:1000 0010,可知最高位为1,因此需要取它的补码,补码为1111 1110,这是一个负数,取最高位作为-号,取最低7位作为数值得到的结果是-126。 程序: 1 #include 2 3int main(void) 4{ 5 unsigned char i = 130; 6 7 printf("%d/n",(char)i); 8 9return0;10 } 运行结果: 2.有符号数--->无符号数 看有符号数的最高位是否为1,如果不为1(为0),则无符号数就直接等于有符号数;如果有符号数的最高位为1,则将有符号数取补码,得到的数就是无符号数。 以char 和unsigned char为例子: 2.1将有符号数3转为无符号数 3的原码是:0000 0011,可知最高位不为1,因此转为无符号数之后也是3。 程序: 1 #include 2 3int main(void) 4{ 5char i = 3; 6 7 printf("%u/n",(unsigned char)i); 8 9return0;10 } 运行结果: 2.2将有符号数-7转为无符号数 -7的原码是:1000 0111,可知最高位为1,因此需要取它的补码,补码为1111 1001,这是一个正数,因此整个数的值就是249。 程序: 1 #include 2 3int main(void) 4{ 5char i = -7; 6 7 printf("%u/n",(unsigned char)i); 8 9return0;10 } 运行结果:

常用的数学符号大全、关系代数符号

常用数学符号大全、关系代数符号 1、几何符号 丄 /∕∠c Θ≡BA 2、 代数符号 X ∧∨ ? ∫ ≠ ≤ ≥ ≈ ∞ : 3、运算符号 如加号( + ),减号(―),乘号(×或?),除号(÷或/), 交集(∩),根号(√),对数(log , Ig ,In ),比(:),微分 积分(/)等。 4、集合符号 U ∩ ∈ 5、 特殊符号 ∑ ∏ (圆周率) 6、 推理符号 Ial 丄 S U ≠≡±≥ ΓΔΘ Λ Ξ On Σ ① X Ψ αβ Y δ ε Zn θ IK λμ ξ OnP σ TU φ X ψω I IlmWV^W 两个集合的并集(U ), (dx ),积分(∫),曲线

i ii iii iv VVigi 血ix X

∈∏∑∕√χ∞∟∠∣∕∕∧∨∩u ∫e .?.?.?: ::S ≈ B= ≠≡≤≥ W 仝< > ? O 丄 "C C 指数0123 : 0123 7、数量符号 如:i, 2+i,a,x,自然对数底e,圆周率n。 &关系符号 如“=”是等号,“≈”是近似符号,“≠”是不等号,“>”是大于符号,“v”是 小于符号,“≥”是大于或等于符号(也可写作“),"≤”是小于或等于符号(也可写作“》”),。“→”表示变量变化的趋势,“s”是相似符号,“B”是全等号,“//” 是平行符号,“丄”是垂直符号,“%”是成正比符号,(没有成反比符号,但可以用成正比符号配倒数当作成反比)“€”是属于符号,“??”是“包含”符号等。 9、结合符号 如小括号“()”中括号“ □”,大括号“”横线“一” 10、性质符号 如正号“ + ”,负号“ —”,绝对值符号“I I ”正负号“ ± ?因为,(一个脚站着的,站不住) ???所以,(两个脚站着的,能站住)总和(∑),连乘(∏),从n个元素中每次取出 r个元素所有不同的组合数(C(r)(n)),幕(A, Ac, Aq, x^n )等。

数学常用符号集

1、几何符号 ⊥∥∠⌒⊙≡≌△ 2、代数符号 ∝∧∨~∫≠≤≥≈∞∶ 3、运算符号 如加号(+),减号(-),乘号(×或·),除号(÷或/),两个集合的并集(∪),交集(∩), 根号(√),对数(log,lg,ln),比(:),微分(dx),积分(∫),曲线积分(∮)等。 4、集合符号 ∪∩∈ 5、特殊符号 ∑π(圆周率) 6、推理符号 |a| ⊥∽△∠∩∪≠≡±≥≤∈← ↑→↓↖↗↘↙∥∧∨ &; § ①②③④⑤⑥⑦⑧⑨⑩ ΓΔΘΛΞΟΠΣΦΧΨΩ αβγδεζηθικλμν ξοπρστυφχψω ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹ ∈∏∑∕√∝∞∟∠∣∥∧∨∩∪∫∮ ∴∵∶∷∽≈≌≒≠≡≤≥≦≧≮≯⊕⊙⊥

⊿⌒℃ 指数0123:o123 7、数量符号 如:i,2+i,a,x,自然对数底e,圆周率π。 8、关系符号 如“=”是等号,“≈”是近似符号,“≠”是不等号,“>”是大于符号,“<”是小于符号,“≥ ”是大于或等于符号(也可写作“≮”),“≤”是小于或等于符号(也可写作“≯”),。“→ ”表示变量变化的趋势,“∽”是相似符号,“≌”是全等号,“∥”是平行符号,“⊥”是垂直 符号,“∝”是成正比符号,(没有成反比符号,但可以用成正比符号配倒数当作成反 比)“∈”是属于符号,“??”是“包含”符号等。 9、结合符号 如小括号“()”中括号“[]”,大括号“{}”横线“—” 10、性质符号 如正号“+”,负号“-”,绝对值符号“||”正负号“±” 11、省略符号 如三角形(△),直角三角形(Rt△),正弦(sin),余弦(cos),x的函数(f(x)),极限(lim) ,角(∠), ∵因为,(一个脚站着的,站不住) ∴所以,(两个脚站着的,能站住) 总和(∑),连乘(∏),从n个元素中每次取出r个元素所有不同的组合数(C(r)(n) ),幂(A,Ac,Aq,x^n)等。 12、排列组合符号 C-组合数

理解C语言有符号数和无符号数

声明网上看到的文章,原文找不到了,原文被转载的不成样子,重复很多,整理花了很长时间,在翻看了维基百科后发现,原文中对于负数原码和补码存在一些问题,修改了一部分,原作者看到后可以联系我。 1、你自已决定是否需要有正负。 就像我们必须决定某个量使用整数还是实数,使用多大的范围数一样,我们必须自已决定某个量是否需要正负。如果这个量不会有负值,那么我们可以定它为带正负的类型。 在计算机中,可以区分正负的类型,称为有符类型(signed),无正负的类型(只有正值),称为无符类型。(unsigned)数值类型分为整型或实型,其中整型又分为无符类型或有符类型,而实型则只有符类型。字符类型也分为有符和无符类型。比如有两个量,年龄和库存,我们可以定前者为无符的字符类型,后者定为有符的整数类型。 2、使用二制数中的最高位表示正负。 首先得知道最高位是哪一位?1个字节的类型,如字符类型,最高位是第7位,2个字节的数,最高位是第15位,4个字节的数,最高位是第31位。不同长度的数值类型,其最高位也就不同,但总是最左边的那位(如下示意)。字符类型固定是1个字节,所以最高位总是第7位。 (红色为最高位) 单字节数:11111111 双字节数: 11111111 11111111 四字节数:11111111 11111111 11111111 11111111 当我们指定一个数量是无符号类型时,那么其最高位的1或0,和其它位一样,用来表示该数的大小。 当我们指定一个数量是无符号类型时,此时,最高数称为“符号位”。为1时,表示该数

为负值,为0时表示为正值。 3、无符号数和有符号数的范围区别。 无符号数中,所有的位都用于直接表示该值的大小。有符号数中最高位用于表示正负,所以,当为正值时,该数的最大值就会变小。我们举一个字节的数值对比: 无符号数:11111111 值:255 1* 27 + 1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20 有符号数:01111111 值:127 1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20 同样是一个字节,无符号数的最大值是255,而有符号数的最大值是127。原因是有符号数中的最高位被挪去表示符号了。并且,我们知道,最高位的权值也是最高的(对于1字节数来说是2的7次方=128),所以仅仅少于一位,最大值一下子减半。 不过,有符号数的长处是它可以表示负数。因此,虽然它的在最大值缩水了,却在负值的方向出现了伸展。我们仍一个字节的数值对比: 无符号数:0 ----------------- 255 有符号数:-128 --------- 0 ---------- 127 同样是一个字节,无符号的最小值是0 ,而有符号数的最小值是-128。所以二者能表达的不同的数值的个数都一样是256个。只不过前者表达的是0到255这256个数,后者表达的是-128到+127这256个数。 一个有符号的数据类型的最小值是如何计算出来的呢? 有符号的数据类型的最大值的计算方法完全和无符号一样,只不过它少了一个最高位(见第3点)。但在负值范围内,数值的计算方法不能直接使用1* 26 + 1* 25 的公式进行转换。在计算机中,负数除为最高位为1以外,还采用补码形式进行表达。所以在计算其值前,

无符号数、有符号数、原码、反码、补码——数据在计算机内部的表示

数据在计算机内部的表示与存储 作者:刘英皓 2013/4/17 今天在做单片机实验的时候,突然对一个问题产生了浓厚的兴趣:数据在计算机内部是怎么表示的?晚上查阅了大量的资料,终于把其中的玄机弄明白了。 资料来源甚广,在此就不一一声明了,感谢!! 数据是什么?它是用来表示信息的。是信息的载体。比如数值、文字、语言、图形、影像等都是不同形式的数据。而在计算机中,无论是数值型数据还是非数值型数据,它们都被表示成了0和1。 既然都变成了0和1,那计算机怎么区别这些不同的信息呢?别担心,它们各在有各自的编码规则。非数值型数据的编码主要有ASCII 码和汉字编码。这里不深究。 数值型数据:它主要有两种形式,有符号数和无符号数 1、有符号数和无符号数 它们的定义估计你都听腻了,我就不重复了,我只强调两点: a.计算机不区分有符号数和无符号数。 b.只有有符号数才有原码、反码和补码。 2、原码、反码和补码 还是两点:

a.正数的原码、反码和补码都一样。 b.负数的反码为原码除符号位的按位取反,补码为反码加1. 注意两点: b1.反码1111 1111的补码是0000 0000. b2.补码1000 0000没有对应的原码和反码,它表示-128,这是规定 3、计算机存储单元中的数据 这个要分两种情况: a.无符号数:直接以对应的二进制表示。 b.有符号数:补码形式表示,无论是计算还是存取。 比如在内存单元中有一个数据为FEH,那么它到底是表示什么?254还是-2?没关系,你说是什么就是什么。因为计算机是不会区分这个数是有符号数还是无符号数的。在你写程序的时候,指定这个量是有符号的,FEH就是一个补码,可以计算得它的真值就是-2,如果指定它是无符号的,那么它就是254。不同的形式在程序中便会有不同的体现。要注意的是在计算中不要超出了数值的范围,以免发生错误。 如有疑问请联系:yinghao1991@https://www.wendangku.net/doc/cb8868217.html,

Verilog带符号数运算

Verilog带符号数运算 摘要:介绍了Verilog带符号数的不同运算。因为Reg和Wire数据默认情况下是无符号的,而在数据处理的情况下,Verilog既要对带符号数据进行各种运算,也要对无符号数和带符号数进行运算,所以简单使用Verilog提供的运算符是不够的。因此研究不同类型数据运算的通用方法是必要的。 关键词:Verilog;带符号数;补码;算术运算 中图分类号:TN911?34 文献标识码:A 文章编号:1004?373X(2015)03?0160?03 Operation of numbers with symbols by Verilog HUI Wei?jun,SHEN Zhao?jun (Yancheng Institute of Technology,Yancheng 224051,China) Abstract:Different operations of data with symbols by Verilog are introduced. Reg and Wire data in the case of default is unsigned,but in the case of data processing,a variety of operations of data with symbols are performed by Verilog,and the unsigned and signed with numbers need to be processed. However,it is not enough to use the operation symbols provided by Verilog. It is necessary to research the general

无符号数除法

在Verilog HDL语言中虽然有除的运算指令,但是除运算符中的除数必须是2的幂,因此无法实现除数为任意整数的除法,很大程度上限制了它的使用领域。并且多数综合工具对于除运算指令不能综合出令人满意的结果,有些甚至不能给予综合。对于这种情况,一般使用相应的算法来实现除法,分为两类,基于减法操作和基于乘法操作的算法。[1] 基于减法的除法器的算法: 对于32的无符号除法,被除数a除以除数b,他们的商和余数一定不会超过32位。首先将a转换成高32位为0,低32位为a的temp_a。把b转换成高32位为b,低32位为0的temp_b。在每个周期开始时,先将temp_a左移一位,末尾补0,然后与b比较,是否大于b,是则temp_a减去temp_b将且加上1,否则继续往下执行。上面的移位、比较和减法(视具体情况而定)要执行32次,执行结束后temp_a的高32位即为余数,低32位即为商。 Verilog HDL 代码 /* 功能:32位除法器 输入参数:被除数a,除数b 输出参数:商yshang,余数yyushu 备注:采用移位、比较和减法(从高位开始)实现的除法运算 本例实现的是32位除法器的例子 */ module division(a,b,yshang,yyushu); input[31:0] a; //被除数 input[31:0] b; //除数 output[31:0] yshang; // output[31:0] yyushu; // reg[31:0] yshang; reg[31:0] yyushu; reg[31:0] tempa; reg[31:0] tempb; reg[63:0] temp_a; reg[63:0] temp_b; always @(a or b) begin tempa <= a; tempb <= b; end integer i;

有符号数与无符号数

1、你自已决定是否需要有正负。 就像我们必须决定某个量使用整数还是实数,使用多大的范围数一样,我们必须自已决定某个量是否需要正负。如果这个量不会有负值,那么我们可以定它为带正负的类型。 在计算机中,可以区分正负的类型,称为有符类型,无正负的类型(只有正值),称为无符类型。 数值类型分为整型或实型,其中整型又分为无符类型或有符类型,而实型则只有符类型。 字符类型也分为有符和无符类型。 比如有两个量,年龄和库存,我们可以定前者为无符的字符类型,后者定为有符的整数类型。 2、使用二制数中的最高位表示正负。 首先得知道最高位是哪一位?1个字节的类型,如字符类型,最高位是第7位,2个字节的数,最高位是第15位,4个字节的数,最高位是第31位。不同长度的数值类型,其最高位也就不同,但总是最左边的那位(如下示意)。字符类型固定是1个字节,所以最高位总是第7位。 (红色为最高位) 单字节数:1111 1111 双字节数:1111 1111 1111 1111 四字节数:1111 1111 1111 1111 1111 1111 1111 1111 当我们指定一个数量是无符号类型时,那么其最高位的1或0,和其它位一样,用来表示该数的大小。 当我们指定一个数量是无符号类型时,此时,最高数称为“符号位”。为1时,表示该数为负值,为0时表示为正值。 3、无符号数和有符号数的范围区别。 无符号数中,所有的位都用于直接表示该值的大小。有符号数中最高位用于表示

正负,所以,当为正值时,该数的最大值就会变小。我们举一个字节的数值对比: 无符号数: 1111 1111 值:255 1* 27 + 1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20 有符号数: 0111 1111 值:127 1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20 同样是一个字节,无符号数的最大值是255,而有符号数的最大值是127。原因是有符号数中的最高位被挪去表示符号了。并且,我们知道,最高位的权值也是最高的(对于1字节数来说是2的7次方=128),所以仅仅少于一位,最大值一下子减半。 不过,有符号数的长处是它可以表示负数。因此,虽然它的在最大值缩水了,却在负值的方向出现了伸展。我们仍一个字节的数值对比: 无符号数: 0 ----------------- 255 有符号数: -128 --------- 0 ---------- 127 同样是一个字节,无符号的最小值是 0 ,而有符号数的最小值是-128。所以二者能表达的不同的数值的个数都一样是256个。只不过前者表达的是0到255 这256个数,后者表达的是-128到+127这256个数。 一个有符号的数据类型的最小值是如何计算出来的呢? 有符号的数据类型的最大值的计算方法完全和无符号一样,只不过它少了一个最高位(见第3点)。但在负值范围内,数值的计算方法不能直接使用1* 26+ 1* 25的公式进行转换。在计算机中,负数除为最高位为1以外,还采用补码形式进行表达。所以在计算其值前,需要对补码进行还原。这些内容我们将在第六章中的二进制知识中统一学习。 这里,先直观地看一眼补码的形式: 以我们原有的数学经验,在10进制中:1 表示正1,而加上负号:-1 表示和1相对的负值。 那么,我们会很容易认为在2进制中(1个字节): 0000 0001 表示正1,则高位为1后:1000 0001应该表示-1。 然而,事实上计算机中的规定有些相反,请看下表:

无符号大整数计算器

C语言及面向对象程序设计实验石家庄铁道大学信息学院 A 数学类 1.题目要求: 高斯消元法求解线性方程组:在线性代数中,学习过用高斯消元法求解线性方程组,用类来实现该方法,并在主函数中进行测试; 2.解题思路: 通常应用高斯消元法的时候,不会直接写出方程组的等式来消去未知数,反而会使用矩阵来计算,将其转化为行阶梯式矩阵,所以程序的算法即线性代数中的矩阵变换为行阶梯式矩阵步骤,所以用一个二维数组存放系数矩阵,一个一维数组存放解值。 3.类的结构(数据和函数); //gauss.h #pragma once #include #include #define N 100 using namespace std; class gauss { private: double a[N][N],b[N]; public: gauss(void); void setvalue(int ); ~gauss(void); }; //gauss.cpp #include "gauss.h" gauss::gauss(void) { }

void gauss::setvalue(int n) { int i,j,k; double a[N][N]; cout<<"请输入"<>a[i][j]; double o,b[N]; for (i=1;i<=n;i++) for (j=i+1;j<=n;j++) if (fabs(a[j][i])>1e-7) { o=a[i][i]/a[j][i]; for (k=i;k<=n+1;k++) a[j][k]=a[j][k]*o-a[i][k]; } for (i=n;i>0;i--) { b[i]=a[i][n+1]/a[i][i]; for (j=i-1;j>0;j--) a[j][n+1]=a[j][n+1]-b[i]*a[j][i]; } cout<<"解得:"< #include #include "gauss.h" using namespace std; void main() { int n; cout<<"请输入未知数个数:"<

有符号数与无符号数的探讨

有符号数与无符号数的探讨 这个问题,要是简单的理解,是很容易的,不过要是考虑的深了,还真有些东西呢。 下面我就把这个东西尽量的扩展一点,深入一点和大家说说。 一、只有一个标准! 在汇编语言层面,声明变量的时候,没有si g ned和u nsi gn d e之分,汇编器统统,将你输入的整数字面量当作有符号数处理成补码存入到计算机中,只有这一个标准!汇编器不会区分有符号还是无符号然后用两个标准来处理,它统统当作有符号的!并且统统汇编成补码!也就是说,d b-20汇编后为:EC,而d b236汇编后也为EC。这里有一个小问题,思考深入的朋友会发现,db是分配一个字节,那么一个字节能表示的有符号整数范围是:-128~+ 127,那么d b236超过了这一范围,怎么可以?是的,+236的补码的确超出了一个字节的表示范围,那么拿两个字节(当然更多的字节更好了)是可以装下的,应为:00EC,也就是说+236的补码应该是00EC,一个字节装不下,但是,别忘了“截断”这个概念,就是说最后汇编的结果被截断了,00EC是两个字节,被截断成EC,所以,这是个“美丽的错误”,为什么这么说?因为,当你把236当作无符号数时,它汇编后的结果正好也是EC,这下皆大欢喜了,虽然汇编器只用一个标准来处理,但是借用了“截断”这个美丽的错误后,得到的结果是符合两个标准的!也就是说,给你一个字节,你想输入有符号的数,比如-20那么汇编后的结果是符合有符号数的;如果你输入236那么你肯定当作无符号数来处理了(因为236不在一个字节能表示的有符号数的范围内啊),得到的结果是符合无符号数的。于是给大家一个错觉:汇编器有两套标准,会区分有符号和无符号,然后分别汇编。其实,你们被骗了。:-) 二、存在两套指令! 第一点说明汇编器只用一个方法把整数字面量汇编成真正的机器数。但并不是说计算机不区分有符号数和无符号数,相反,计算机对有符号和无符号数区分的十分清晰,因为计算机进行某些同样功能的处理时有两套指令作为后备,这就是分别为有符号和无符号数准备的。但是,这里要强调一点,一个数到底是有符号数还是无符号数,计算机并不知道,这是由你来决定的,当你认为你要处理的数是有符号的,那么你就用那一套处理有符号数的指令,当你认为你要处理的数是无符号的,那就用处理无符号数的那一套指令。加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:m ul di v m ovz x…是处理无符号数的,而这些:i m ul i di v

数学运算符号

数学符号的种类 数量符号 如:i,2+i,a,x,自然对数 底e,圆周率π。 运算符号 如加号(+),减号(-), 乘号(×或·),除号(÷或/),两个集合的并集(?),交集(?),根号(↗),对数(log,lg,ln),比(:),微分(dx),积分(?),曲线积分(?)等。 关系符号 如“=”是等号,“≈”是近 似符号,“≠”是不等号,“>” 是大于符号,“<”是小于符号,“?”是大于或等于符号(也可写 作“≤”),“?”是小于或等于 符号(也可写作“≥”),。“→”表示变量变化的趋势,“∽”是相 似符号,“≌”是全等号,“?” 是平行符号,“≧”是垂直符号,“↘”是成正比符号,(没有成反 比符号,但可以用成正比符号配倒 数当作成反比)“?”是属于符号,“?”是“包含”符号等。 结合符号 如小括号“()”中括号“[]”,大括号“{}”横线“—” 性质符号 如正号“+”,负号“-”, 绝对值符号“| |”正负号“±” 省略符号 如三角形(△),直角三角形(Rt△),正弦(sin),余弦(cos),x的函数(f(x)),极限(lim),角(?), ?因为,(一个脚站着的,站不住) ?所以,(两个脚站着的,能站住)总和(↖),连乘(?),从n个元素中每次取出r个元素所有不同的组合数(C(r)(n) ),幂(A,Ac,Aq,x^n)等。 排列组合符号 C-组合数 A-排列数 N-元素的总个数 R-参与选择的元素个数 !-阶乘,如5! =5×4×3×2×1=120 C-Combination- 组合 A-Arrangement-排列 离散数学符号(未全) ?全称量词 ?存在量词 ├ 断定符(公式在L中可证) ╞ 满足符(公式在E上有效,公式在E上可满足) ┐ 命题的“非”运算 ? 命题的“合取”(“与”)运算 ? 命题的“析取”(“或”,“可兼或”)运算 → 命题的“条件”运算 ?命题的“双条件”运算的 A<=>B 命题A 与B 等价关系 A=>B 命题 A与 B的蕴涵关系 A* 公式A 的对偶公式 wff 合式公式

带符号数的原码、反码与补码分析

一.带符号数的原码、反码与补码 所谓带符号数,其实就是一个二进制数据,它的最高位所代表的是符号,其余位是其“绝对值”。例如0101_0011,这个数据如果是带符号数,那么最高位的0就是代表这个数据为正数,其后的101-0011则代表这个数据的绝对值,为+83D。如果是1101_0011,则代表-83D。 1.1 原码 原码就是按照正数的符号位为0,负数的符号位为1,其他位就是数据的绝对值即可。例如当机器字长为8bit的二进制数时,它的最高位为符号位,因此其余的7bit位数据的绝对值。因此原码所能表示的数据范围是: - (2n-1-1)~+(2n-1-1) 当字长为8bit,则原码能表示的范围就是:-127~+127 例如83的原码就是:0101_0011 当字长为16bit,则原码能表示的范围就是:-32767~+32767 例如-83的原码就是:1000_0000_0101_0011 1.2 反码 对于一个带有符号位的二进制数来说,正数的反码与其原码相同,负数的反码为其原码除符号位外其余各位按位取反。 例如当字长为8bit时,+83D的反码就是:0101_0011,-83D的反码就是1010_1100 负数的反码与原码有很大的差别,一般情况下,反码主要用来当做求二进制数补码的中间形式。反码所表示的数据范围与原码相同: - (2n-1-1)~+(2n-1-1) 1.2 补码 正数的补码与其原码相同,负数的补码为其反码在最低位加1。 例如: X=+101_1011 [X]原码=0101_1011 [X]补码=0101_1011 X=-101_1011 [X]原码=1101_1011 [X]补码=1010_0101 补码表示的范围是: - 2n-1~+(2n-1-1)

计算机组成原理_计算机的运算方法_61 无符号数和有符号数_

6.1 无符号数和有符号数

寄存器的位数 反映无符号数的表示范围 8 位 0 ~ 255 16 位 0 ~ 65535

带符号的数 符号数字化的数 + 0.10110 1011小数点的位置+ 11000 1100 小数点的位置– 1100 1 1100 小数点的位置 – 0.10111 1011 小数点的位置真值 机器数 1. 机器数与真值

2. 原码表示法—整数 带符号的绝对值表示 x 为真值n 为整数的位数 如x = +1110 [x ]原 = 0 , 1110 [x ]原 = 24 + 1110 = 1 , 1110 x = 1110[x ]原 = 0,x 2n > x ≥ 0 2n x 0 ≥ x > 2 n 用 逗号 将符号位和数值部分隔开

x 为真值 如x = + 0.1101 [x ]原 = 0 . 1101 x = – 0.1101[x ]原 = 1 – (–0.1101) = 1 . 1101 x 1 > x ≥ 0 [x ]原 = 1 – x 0 ≥ x >–1 x = – 0.1000000 [x ]原 = 1 – (– 0.1000000) = 1 . 1000000 x = + 0.1000000[x ]原 = 0 . 1000000 用 小数点 将符号位和数值部分隔开 用 小数点 将符号位和数值部分隔开 2. 原码表示法—小数

例 6.1 已知 [x ]原 = 1.0011 求 x 解:例 6.2 已知 [x ]原 = 1,1100 求 x 解:x = 1 – [x ]原 = 1 – 1.0011 = –0.0011 x = 24 – [x ]原 = 10000 – 1,1100 = –1100 – –0.0011 1100由定义得 由定义得

有符号数加法问题

有符号数加法问题 问题:两个8位数有符号相加,结果要求是16位。 解题思路:如果两个有符号数相加没有溢出,则将加法的结果通过CBW指令扩展成16位。如果加法产生了溢出,则判断加法是否产生了进位,如果没有产生进位,说明这两个有符号数都是正数,此时,在8位的结果前补上00H,将其变成16位的结果;如果产生了进位,说明这两个有符号数都是负数,此时,在8位结果前补上FFH,将其变成16位的结果。 举例: ●两个有符号数01H(真值为1)和02H(真值为2)做加法运算, 因为-128≦1+2≦127,这说明两数相加不会产生溢出,加法的结果为03H(真值为3),通过CBW指令进行扩展,得到16位的结果0003H(真值为3)。 ●两个有符号数F6H(真值为-10)和F5H(真值为-11)做加法运 算,因为-128≦(-10)+(-11)≦127,这说明两数相加不会产生溢出,加法的结果为EBH(真值为-21),通过CBW指令进行扩展,得到16位的结果FFEBH(真值为-21)。 ●两个有符号数64H(真值为100)和65H(真值为101)做加法运 算,因为100+101≧127,这说明两数相加后会产生溢出,加法的结果为C9H(真值为-55),此时加法没有产生进位,说明两个加数都是正数,在C9H前补上00H得到16位的结果00C9H(真值为201)。

两个有符号数9CH(真值为-100)和9BH(真值为-101)做加法运算,因为(-100)+(-101)≦-128,这说明两数相加后会产生溢出,加法的结果为37H(真值为55),此时加法产生了进位,说明两个加数都是负数,在37H前补上FFH得到16位的结果FF37H(真值为-201)。 通过程序解决该问题(被加数和加数分别放在AL和BL寄存器中,16位的结果放AX中) ADD AL, BL JO OVERFLOW ;如产生溢出,则转移到OVERFLOW CBW ;该指令不会影响任何标志位 JMP NEXT OVERFLOW: JC L1 ;产生进位说明两个数都是负数AND AH, 00H JMP NEXT L1: OR AH, FFH NEXT: …..

无符号数词法分析程序

#include #include #include #define DIGIT 1 #define POINT 2 #define OTHER 3 #define POWER 4 #define PLUS 5 #define MINUS 6 #define UCON 7 //Suppose the class number of unsigned constant is 7 #define ClassOther 200 #define EndState -1 int w,n,p,e,d; int Class; //Used to indicate class of the word int ICON; float FCON; static int CurrentState; //Used to present current state, the initial value:0 int GetChar (void); int EXCUTE (int,int); int LEX (void); //_____________________________________________________________________________ _________________________ int HandleOtherWord (void) { return ClassOther; } //_____________________________________________________________________________ __________________________ int HandleError (void) {printf ("Error!\n"); return 0;} //_____________________________________________________________________________ __________________________ int GetChar (void) { int c; c=getchar( ); if(isdigit(c)) {d=c-'0';return DIGIT;} if (c=='.') return POINT; if (c=='E'||c=='e') return POWER; if (c=='+') return PLUS; if (c=='-') return MINUS;

关于有符号数、无符号数和数据类型的总结

一、 CPU只会根据输入信号进行逻辑运算,在硬件级别是没有有符号无符号的概念,运算结束会根据运算前的信号和输出信号来设置一些标志位,是不是有符号由写程序的人决定,标志位要看你把操作数当有符号还是无符号来选择,就像内存中的数据,你可以按照需要来解析,原始数据在那里,你要按什么数据格式来解析在于自己的选择,所以玩汇编的要做到心里有数,加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:mul div movzx … 是处理无符号数的,而这些:imul idiv movsx … 是处理有符号的。举例来说:内存里有一个字节x 为:0x EC ,一个字节y 为:0x 02 。当把x,y当作有符号数来看时,x = -20 ,y = +2 。当作无符号数看时,x = 236 ,y = 2 。下面进行加运算,用add 指令,得到的结果为:0x EE ,那么这个0x EE 当作有符号数就是:-18 ,无符号数就是238 。所以,add 一个指令可以适用有符号和无符号两种情况。(呵呵,其实为什么要补码啊,就是为了这个呗,:-)) 乘法运算就不行了,必须用两套指令,有符号的情况下用imul 得到的结果是:0x FF D8 就是-40 。无符号的情况下用mul ,得到:0x 01 D8 就是472 。 二、 C又是可怕的,因为它把机器层面的所有的东西都反应了出来,像这个有没有符号的问题就是一例(java就不存在这个问题,因为它被设计成所有的整数都是有符号的)。为了说明c的可怕特举一例: #include #include int main() { int x = 2; char * str = "abcd"; int y = (x - strlen(str) ) / 2; printf("%d\n",y);

符号运算

与Wolfram公司(Mathematics的开发公司)相比,Mathworks公司一直以矩阵计算和强大的数据处理能力见长,而符号计算非强项。1993年,mathworks公司从加拿大Waterloo Maple公司购买了maple的内核技术,作为MA TLAB符号运算与推导的平台,开发了用以进行符号计算的基本符号运算工具箱和扩展符号运算工具箱,从而解决了MA TLAB在符号计算方面的缺陷。 MA TLAB7.0的符号运算工具箱已上升到3.1.1版本,它几乎可以完成所有的符号运算功能,包括符号函数与符号方程的定义、运算、复合、化简、符号矩阵的计算、符号微分、符号积分、符号代数方程、符号微分方程的求解、符号积分变换和符号特殊函数。 在MA TLAB7.0的符号数学工具箱中,符号表达式含有符号函数和符号方程两种形式,它是表示数字、函数或变量的字符串或字符串组。字符就是符号变量的值。因此在MA TLAB的源程序中符号表达式被表示成字符串和字符串组。符号函数和符号方程的区别是符号函数没有等号,而符号方程必须有等号。 符号变量的定义 MA TLAB有默认的符号自变量,但在各种情况下默认的自变量是不同的。系统默认的自变量主要有x、x1、y、y1、z、v、u、t、theta、alpha。对于这些变量MA TLAB 的默认规则与平时数学习惯大致相同,即: 当这些变量中的某一个与其他变量组成符号数学表达式时,这个变量即为默认的自变量; 当这些变量中的某几个组成符号数学表达式是,默认自变量的顺序是:x>x1>y>y1>z>v>u>t>theta>alpha 例如:

当数学表达式为cos(2*x*a^2)时,默认的自变量为x; 当数学表达式为cos(2*x*v)时,默认的自变量为x; 当数学表达式为cos(2*t*alpha)时,默认的自变量为t; 符号变量可以通过命令syms和sym定义,syms命令一个可以定义一个或多个符号变量。sym一个只能定义一个符号变量。 >> syms x y z t >> who Y our variables are: t x y z >> syms u >> who Y our variables are: t u x y z >> x=sym('x'); >> t=sym('t'); >> z=sym('z'); >> y=sym('y'); >> who Y our variables are: ans t x y z 符号表达式的定义 MA TLAB7.0当中,符号表达式可以通过基本赋值语句,采用单引号或sym/syms

汇编中有符号与无符号数的区分

汇编中有符号与无符号数的区分 一、只有一个标准! 在汇编语言层面,声明变量的时候,没有signed 和unsignde 之分,汇编器统统,将你输入的整数字面量当作有符号数处理成补码存入到计算机中,只有这一个标准!汇编器不会区分有符号还是无符号然后用两个标准来处理,它统统当作有符号的!并且统统汇编成补码!也就是说,db -20 汇编后为:EC ,而db 236 汇编后也为EC 。这里有一个小问题,思考深入的朋友会发现,db 是分配一个字节,那么一个字节能表示的有符号整数范围是:-128 ~ +127 ,那么db 236 超过了这一范围,怎么可以?是的,+236 的补码的确超出了一个字节的表示范围,那么拿两个字节(当然更多的字节更好了)是可以装下的,应为:00 EC,也就是说+236的补码应该是00 EC,一个字节装不下,但是,别忘了“截断”这个概念,就是说最后的结果被截断了,00 EC 是两个字节,被截断成EC ,所以,这是个“美丽的错误”,为什么这么说?因为,当你把236 当作无符号数时,它汇编后的结果正好也是EC ,这下皆大欢喜了,虽然汇编器只用一个标准来处理,但是借用了“截断”这个美丽的错误后,得到的结果是符合两个标准的!也就是说,给你一个字节,你想输入有符号的数,比如-20 那么汇编后的结果是正确的;如果你输入236 那么你肯定当作无符号数来处理了(因为236不在一个字节能表示的有符号数的范围内啊),得到的结果也是正确的。于是给大家一个错觉:汇编器有两套标准,会区分有符号和无符号,然后分别汇编。其实,你们被骗了。:-) 二、存在两套指令! 第一点说明汇编器只用一个方法把整数字面量汇编成真正的机器数。但并不是说计算机不区分有符号数和无符号数,相反,计算机对有符号和无符号数区分的十分清晰,因为计算机进行某些同样功能的处理时有两套指令作为后备,这就是分别为有符号和无符号数准备的。但是,这里要强调一点,一个数到底是有符号数还是无符号数,计算机并不知道,这是由你来决定的,当你认为你要处理的数是有符号的,那么你就用那一套处理有符号数的指令,当你认为你要处理的数是无符号的,那就用处理无符号数的那一套指令。加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:mul div movzx …是处理无符号数的,而这些:imul idiv movsx …是处理有符号的。 举例来说: 内存里有一个字节x 为:0x EC ,一个字节y 为:0x 02 。当把x,y当作有符号数来看时,x = -20 ,y = +2 。当作无符号数看时,x = 236 ,y = 2 。下面进行加运算,用add 指令,得到的结果为:0x EE ,那么这个0x EE 当作有符号数就是:-18 ,无符号数就是238 。所以,add 一个指令可以适用有符号和无符号两种情况。(呵呵,其实为什么要补码啊,就

相关文档
相关文档 最新文档