C++有符号和无符号数的转换
本文转自:http://www.94cto.com/index/Article/content/id/59973.html
1.引例:
今天在做了一道关于有符号数和无符号数相互转换及其左移/右移的问题,被它们之间的转换原理和位移原理搞得头大了。真的很后悔本科的时候没有认真学习《计算机组成原理》/《计算机操作系统》等计算机基础课程。以下是我根据相关知识回顾和整理的材料,如有和某某的文章有雷同之处,请勿见怪。另外也希望看到这篇文章的同志们能够有所收获吧。
#include <cstdio>
#include <iostream>
using namespace std; int main()
{
unsigned short int ui;
signed short int si;
ui = (unsigned short int)0x8000u;
si = (signed short int)0x8000;
printf("ui = %u\n",ui);
printf("si = %d\n",si);
ui = ui>>;
si = si>>;
printf("ui = %u\n",ui);
printf("si = %d\n",si);
cout<<"------------------------------"<<endl; ui = (unsigned short int)0x8000u;
si = (signed short int)0x8000;
printf("%u\n",ui);
printf("%d\n",si);
ui = ((signed short int)ui>>);//先类型转换,再移位,
si = ((unsigned short int)si>>);
printf("%u\n",ui);
printf("%d\n",si);
cout<<"------------------------------"<<endl; ui = (unsigned short int)0x8000u;
si = (signed short int)0x8000;
printf("%u\n",ui);
printf("%d\n",si);
ui = ui<<;
si = si<<;
printf("%u\n",ui);
printf("%d\n",si);
cout<<"-------------------------------"<<endl; ui = (unsigned short int)0x8000u;
si = (signed short int)0x8000;
printf("%u\n",ui);
printf("%d\n",si);
ui = ((signed short int)ui<<);
si =((unsigned short int)si<<);
printf("%u\n",ui);
printf("%d\n",si);
return ;
}
运行结果

2.概念
在计算机中,可以区分正负类型的数,成为“有符号数”(signed);无正负类型的数(只有整数类型),成为“无符号数”(unsigned)。简明的说,无符号说就是其所有的位数都用来表示数值的大小,有符号数除最高位来表示数值的正负外(0表示正数;1表示负数),其余各位用来表示数值的大小。举个例子说明一下:十机制数 正数255 二进制表达形式:1111 1111
十机制数 负数-1 二进制表达形式:1111 1111
可见-1的二进制的最高位为红色的1,可是为什么其表达形式为1111 1111而不是1000 0001呢?这就关于任何数在计算机内是以补码形式存储问题。下面会介绍的,在此先不详细说明了。
3.存储范围
从前面的介绍可以知道,由于有符号数的最高位被拿来用作符号位,所以它所能够表达的最大数值要小于无符号数所能够表达的最大数值。还是举个例子来说明一下吧:
无符号数:1111 1111 十进制值:255
有符号数:0111 1111 十进制值:127
这是有人可能会提出这样的疑问:有符号数所能够表达的数值范围会不会小于无符号数所能够表达的数值范围呢?
呵呵,答案是否定的!虽然有符号数在表达最大值上的能力减弱了,但是它能够表达负数。负数的个数可以弥补其不足。来让我们比较一下:
一个字节的无符号数的表达数值范围是:[0,255]
一个字节的有符号数的表达数值范围是:[-128,0),[0,127]
可见它们都能够表示256个数。
4.各种码(原码/反码/补码)
有些人也许会这样认为"-1"(双字节)在计算机中的表达形式为1000 0000 0000 0001,可是实际上不是的。计算机是以其补码的形式进行表达的,即“-1”(双字节)的表达形式是1111 1111 1111 1111。
说一下各种码的概念吧。
原码:一个整数,按照绝对值的大小转换成二进制数,最高位为符号位。
反码:将原码除最高位(符号位)外,其余各位按位取反,所得到的二进制码。正数的反码为原码。
补码:反码最低位加1即为补码。
关于负数的补码求法说明一下,先得到其反码,之后将反码加1即可。有些大神根据其原码,闭眼即得,这种能力需要修炼一下啊。
这时有些人可能会说,为什么要引入补码的形式呢?直接按照原码存储不就省事很多吗?嘿嘿,要记住,有些事情并不是你想省事就能省事的。好了来欣赏一下补码的优势吧。
计算机的带符号数用补码表示的优点:
1负数的补码与对应正数的补码之间的转换可以用同一种方法-求补运算完成,可以简化硬件。 2 可将减法变为加法,这样减法就可以用加法器进行计算了。 3 两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。
心算求补(大神求补算法):
从最低位开始至找到的第一个1均不变,符号位不变,这之间的各位“求反”(0变1;1变0)。
原码:1010 1001 补码:1101 0111.
5.有符号数与无符号数的相互转换
无符号整数和有符号整数之间进行强制类型转换时,位模式不改变。
有符号数转换为无符号数时,负数转换为大的正数,相当于在原值上加上2的n次方,而正数保持不变。
无符号数转换为有符号数时,对于小的数将保持原值,对于大的数将转换为负数,相当于原值减去2的n次方。
当表达式中存在有符号数和无符号数类型时,所有的操作都自动转换为无符号类型。可见无符号数的运算优先级高于有符号数。
unsigned int a = 20;
signed int b = -130;
运算一下结果是 b>a
6.转换大餐
有符号数的转换
| 原类型 | 目标类型 | 转换方法 |
| char |
short |
符号位扩展 |
| char | long | 符号位扩展 |
| char | unsigned char | 最高符号位失去位意义,变为数据位 |
| char | unsigned short | 符号位扩展到short;然后从short转到unsigned short |
| char | unsigned long | 符号位扩展到long;然后从long转换到unsigned long |
| char | float | 符号位扩展到long;然后从long转到float |
| char | double | 符号位扩展到long;然后从long转换到double |
| char | long double | 符号位扩展到long;然后从long转换到long double |
| short | char | 保留低位字节 |
| short | long | 符号位扩展 |
| short | unsigned char | 保留低位字节 |
| short | unsigned short |
最高为失去意义,变为数据位 |
| short | unsigned long | 符号位扩展到long;然后从long转到unsigned long |
| short | float | 符号位扩展到long;然后从long转到float |
| short | double | 符号位扩展到long;然后从long转到double |
| short | long double | 符号位扩展到long;然后从long转换到long double |
| long | char | 保留低位字节 |
| long | short | 保留低位字节 |
| long | unsigned char | 保留低位字节 |
| long | unsigned short | 保留低位字节 |
| long | unsigned long | 最高为失去意义,变为数据位 |
| long | float | 使用单精度浮点数表示,可能失去精度 |
| long | double | 使用单精度浮点数表示,可能失去精度 |
| long | long double | 使用单精度浮点数表示,可能失去精度 |
无符号数的转换
| 原类型 | 目标类型 | 转换方法 |
| unsigned char | char | 最高为作符号位 |
| unsigned char | short | 0扩展 |
| unsigned char | long | 0扩展 |
| unsigned char | unsigned short | 0扩展 |
| unsigned char | unsigned long | 0扩展 |
| unsigned char | float | 转换到long;然后从long转换到float |
| unsigned char | double | 转换到long;然后从long转换到double |
| unsigned char | long double | 转换到long;然后从long转换到long double |
| unsigned short | char | 保留低位字节 |
| unsigned short | short | 最高为作符号位 |
| unsigned short | long | 0扩展 |
| unsigned short | unsigned char | 保留低位字节 |
| unsigned short | unsigned long | 0扩展 |
| unsigned short | float | 转换到long;然后从long转换到float |
| unsigned short | double | 转换到long;然后从long转换到double |
| unsigned long | long double | 转换到long;然后从long转换到long double |
| unsigned long | char | 保留低位字节 |
| unsigned long | short | 保留低位字节 |
| unsigned long | long | 最高位作符号位 |
| unsigned long | unsigned char | 保留低位字节 |
| unsigned long | unsigned short | 保留低位字节 |
| unsigned long | float | 转换到long;然后从long转换到float |
| unsigned long | double | 直接转换到double |
| unsigned long | long double | 转换到long;然后从long转换到long double |
7.各种数据类型所占字节
32位平台下:

ps:文中若有不当之处,请指出!
C++有符号和无符号数的转换的更多相关文章
- 关于有符号数和无符号数的转换 - C/C++
转载自:http://www.94cto.com/index/Article/content/id/59973.html 1.引例: 今天在做了一道关于有符号数和无符号数相互转换及其左移/右移的问题, ...
- JAVA byte有无符号数的转换
如果你只需要对英文文本的每个字节进行数据处理,则无需考虑有符号数和无符号数的转换问题: 但如果你需要对含有中文的文本进行字节处理,则可能需要考虑有无符号数的转换问题. 以下代码均为Java代码. 1. ...
- jni——如何转换有符号与无符号数
java数据结构默认均为有符号数,而通过jni转换到c/c++层,却不一定是有符号数. 如若在java中存储的即为无符号数,则在jni中可将jbyte直接进行类型转换. 若进行操作,则可在计算时,先将 ...
- 【C语言学习趣事】_33_关于C语言和C++语言中的取余数(求模)的计算_有符号和无符号数的相互转换问题
最近再次复习C++语言,用的教材是<C++ Primer>这本教材, 看到第二章的时候,里面有个问题困扰了我. 于是想上网查查怎么回事, 结果看了很久都没有得到一个满意的答案. 书上有这么 ...
- c语言中为什么左移不分符号数无符号数,而右移分呢??
因为在C语言标准中,只规定了无符号数的移位操作是采用逻辑移位(即左移.右移都是使用的逻辑左移和逻辑右移).而对于有符号数,其左移操作还是逻辑左移,但右移操作是采用逻辑右移还是算术右移就取决于机器了!( ...
- 关于C语言中不同类型数据进行计算 有符号和无符号数进行计算
float是8个有效位, 做个试验: 输出如下: 上面说明了什么: 1, 18/2.2 是除不尽的, 因为是define,所以没有给ratio变量赋值类型,但是从sizeof输出的结果是8,所以系统默 ...
- signed 与 unsigned 有符号和无符号数
unsigned int a = 0; unsigned int b = -1; // b 为 0xffffffff unsigned int c = a - 1; // c 为 0xffffffff
- C语言-无符号数与有符号数不为人知的秘密
一.无符号数与有符号数 1.计算机中的符号位 数据类型的最高位用于标识数据的符号 -最高位为1,表明这个数为负数 -最高位为0,表明这个数为正数 #include <stdio.h> in ...
- C语言中无符号数和有符号数之间的运算
C语言中无符号数和有符号数之间的运算 C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算当然是返回0或1了. un ...
随机推荐
- php显示距当前多长时间
<?php header("Content-type: text/html; charset=utf-8");date_default_timezone_set('PRC') ...
- 第6章 Overlapped I/O, 在你身后变戏法 ---被激发的 File Handles -3
最简单的 overlapped I/O 类型,是使用它自己的文件 handle 作为同步机制.首先你以 FILE_FLAG_OVERLAPPED 告诉 Win32 说你不要使用默认的同步 I/O.然后 ...
- ArcGIS RunTime SDK for Android之Features and graphics
今天是我开通博客园的第一天,希望以后可以多在博客园上分享自己的学习心得,记录自己的学习历程.最近在学习ArcGIS RunTime SDK for Android,所以第一篇随笔就从这里来吧.官网的教 ...
- wmic命令
WMIC扩展WMI(Windows Management Instrumentation,Windows管理工具) ,提供了从命令行接口和批命令脚本执行系统管理的支持. 一.如何使用帮助文档: 1.w ...
- python之字典
1.用{}创建字典 代码: 1 2 x = {"a":"1", "b":"2"} print x 输出: {'a': ' ...
- Java基础语法(上篇)
Java基础语法(上篇) 知识概要: (1)关键字的表示与规范 (2)标示符 (3)注释 (4 ...
- C#钩子类 几乎捕获键盘鼠标所有事件
using System; using System.Text; using System.Runtime.InteropServices; using System.Reflection; usin ...
- 比较两个文件不同以及生成SQL插入语句
Tips 做一个终身学习的人! 日拱一卒,功不唐捐. 今天有个小小的需求,具体需求是这样的: 有两个文本文件,每个文件都有一些字符串文本: 比较第一个文件中,在第二个文件中,不存在的字符串文本: 把这 ...
- phpstudy升级mysql数据库
因为MySQL支持全文索引的只有5.6以上,而我下的phpstudy只有5.5的版本,在导入数据库的时候因为该数据库的表内有使用全文索引,因此必须升级phpstudy的mysql版本,这里就把自己当升 ...
- sa账户和密码丢失如何找回
来自:http://www.cnblogs.com/xred/archive/2012/03/09/2386185.html 在网上看了很多如何修改SQLServer2005的密码的方法.大多数都是转 ...