IT知识库 购物 网址 游戏 小说 歌词 快照 开发 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 编程 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> C# -> 关于负数 -> 正文阅读

[C#]关于负数

关于负数 本文主要是想阐述清楚以下几个知识点:
  1、与负数相关的一些基础概念;
  2、负数的二进制和十进制之间的转换;
  3、负数与数据类型;
一、基础概念
  机器数:数值在计算机中的二进制表示形式,叫做这个数值的机器数;机器数是带符号的,在计算中用一个数的最高位存放符号,正数为0,负数为1;
  真值:因为负数的机器数,最高位为符号位,所以机器数的形式值就不等于真正的数值,不像正数那么“一目了然”。例如1000 0011,如果是负数,则bit7为1,其真正十进制数值为-3,而不是形式值131(当然如果不是负数,那么确实就是131);所以,为了区别起见,将带符号位的机器数对应的真正数值称为机器数的真值;
  补码:负数在计算机中,是以其绝对值的补码形式表示。机器数的补码可由其原码(原码即数值的二进制机器数)计算得到。如果数值为正数,则其原码和补码一样;如果数值为负数,则其补码是他对应的原码(除符号位外)取反,并在末尾加一得到。
二、负数的二进制和十进制转换
负数的十进制转二进制:Math.abs(number)-1,再取反,简称“减一取反”。
负数的二进制转十进制:先取反,再Math.abs(number)+1,简称“取反加一”
  取反也叫做反码,负数的二进制直接是看不出来其十进制的表示(也就是真值),所以通过“取反加一”可以得到其补码,在计算补码的过程中,符号位是不参与计算。
  举例:
  1、数值-110十进制转二进制
    1)减1:Math.abs(110)-1=109
    2)取反:109的二进制表示为:0110 1101,取反为 1001 0010
  2、数值-110二进制转十进制
    1)取反:1001 0010,取反为0110 1101
    2)加1:加1后为0110 1110,等于110,因为其二进制最高位为1,所以是负数,也就是-110
三、负数与数据类型
  1、有符号和无符号数据类型
    在编程语言中,一般都存在有符号数据类型和无符号数据类型。无符号类型也就是没有符号位。例如有符号byte类型,范围为-128~127,而无符号byte类型,因为最高位不用存储符号,而可以直接存储数值,则为0~255,当然也就无法存储(表示)负数。
  2、有符号和无符号数据类型之间的转换
    以C#语言举例,byte为无符号,sbyte为有符号。
    byte b1 = –100;
    sbyte b2 = 250;
    这两行代码都无法通过编译,原因也简单,赋给变量的值都超出了其能存储的范围。而在实际项目中,我们经常会遇到,我必须用byte来存储对方发送过来的sbyte数据。而在c#中,通过下面方式处理了有无符号数据类型之间的转换:
    byte b1 = –100&0xff;  // 156
    sbyte b2 = (sbyte)Convert.ToInt32(250); // -6
    代码是解决了转换,但为什么可以正确转换,结果又是如何而来,我们分析一下:-100转换为无符号方法,首先得到其二进制形式1001 1100,因为要将其转换为无符号,则其最高位不再是符号位,而是当作具体数值位来计算,则为156;250转换为有符号方法,首先得到其二进制形式1111 1010,将其最高位视为符号位,因为是负数,按照“取反加一”方式转换为十进制,则为-6。
无符号转有符号数据类型:获取数值的二进制原码,将最高位视为符号位,再将其转换为十进制,得到的数值即为转换后的值。
有符号转无符号数据类型:获取数值的二进制原码,将最高位视为存储数值的位,再将其转换为十进制,得到的数值即为转换后的值。
  3、强制类型转换带来的数值丢失
    当有符号和无符号之间转换时,如果是符号相同,且目标数据类型bit位数大于或等于当前数据类型,例如sbyte和int32,或byte和uint32,则不会出现数据“丢失”(暂且这么叫),这里主要讨论另外两种情况:
    1、向小于自身数据类型bit位数的类型转换,例如int32转换为sbyte或byte。
      显而易见,如果数值是一个大于sbyte或byte的数值,则转换后,会存在丢失。这里主要从二进制的角度分析如何丢失?转换后的数值是怎么来的?
      例如
      int32 a1 = 3000;
      sbyte a2 = (sbyte)a1; //输出-72
      byte a3 = (byte)a3;//184
      分析:3000的二进制为0000 0000 0000  0000 0000 1011 1011 1000,而sbyte只能存储0~255,所以只能取bit0~bit7,也就是1011 1000,而sbyte为有符号数据类型,所以bit7为符号位,按“取反加一”得到72,加上符号,也就得到-72。
      而a3,因为是byte无符号类型,所以1011 1000,直接取十进制即可,也就得到184。这种情况下,因为发生了数据位的“截取”,所以即使再类型转换回去,也无法得到原值,所以是真正的丢失。
    2、向大于或等于自身数据类型bit位数,且符号位不同的数据类型转换,例如sbyte转换为byte,sbyte(有符号)转换为uint32(无符号),或byte(无符号)转换为int32(有符号)。
      例如:
      sbyte a1 = –10;
      byte a2 =  -10&0xff;// 246
      int32 a3 = a1;// -10
      uint32 a4 = (unit32)a1; // 4294967286
      分析:a3属于和sbyte相同符号,int32位数又大于sbyte,所以数据不会丢失,还是-10。而a2,因为要将-10转换为无符号,所以直接无视其符号位,得到246。a4这里稍微详细说一下,首先-10的二进制为1111 0110,当转换为32bit时,-10的负数形式则为,得到:
      1111 1111 1111 1111 1111 1111 1111 0110
      因为要转换为uint32无符号类型,所以无视符号位,转换为十进制得到4294967286。
      转换后,虽然数值和转换前原值不同,但转换回原类型,仍然能够拿到正确的原值。所以这种转换情况,会得到”非预期的数值“,但并没有丢失,转换回去,依然能够拿回原值。
总结:
  文本主要描述了一些关于负数的基础概念,以及负数的二进制和十进制之间转换。也分析了不同符号或不同数据类型之间转换,可能会发生的一些“丢失数值“或”得到非预期的数值“情况。都是些非常基础的知识,仅仅为了记录一下。如果文中有理解错误的地方,烦请指出,感谢!
上一篇文章      下一篇文章      查看所有文章
加:2017-10-12 23:21:44  更:2017-10-12 23:21:46 
 
  C# 最新文章
字符串阵列分别输出元素的索引,原值和长度
格式化你的字符串
C#宣告一个变量
C#中级
拆分一个字符串并把每个字符单独输出
通过手机号定位归属地
C# 取Visio模型信息的简易方法
物联网框架SuperIO 2.2.9和ServerSuperIO 2
使用Microsoft Unity进行日志记录
AutoMapper(二)
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 新闻资讯 小游戏 Chinese Culture 股票 三丰软件 开发 中国文化 网文精选 阅读网 看图 日历 万年历 2018年10日历
2018-10-24 3:20:36
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库