?? 理解有符號數和無符號數 - java-jinguo - javaeye技術網站.htm
字號:
?<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<!-- saved from url=(0037)http://jinguo.javaeye.com/blog/212049 -->
<HTML dir=ltr xml:lang="zh-CN"
xmlns="http://www.w3.org/1999/xhtml"><HEAD><TITLE>理解有符號數和無符號數 - Java-Jinguo - JavaEye技術網站</TITLE>
<META http-equiv=Content-Type content="text/html; charset=UTF-8">
<META
content=" 理解有符號數和無符號數負數在計算機中如何表示呢? 這一點,你可能聽過兩種不同的回答。 一種是教科書,它會告訴你:計算機用“補碼”表示負數。可是有關“補碼”的概念一說就得一節課,這一些我們需要在第6章中用一章的篇幅講2進制的一切。再者,用“補碼”表示負數,其實一種公式,公式的作用在于告訴你,想得問題的答案,應該如何計算。卻并沒有告訴你為什么用這個公式就可以和答案? 另一種是一些程序員告訴你 ..."
name=description>
<META content="理解有符號數和無符號數 理解有符號數和無符號數" name=keywords><LINK
href="/images/favicon.ico" type=image/x-icon rel="shortcut icon"><LINK
title=Java-Jinguo href="/rss" type=application/rss+xml rel=alternate><LINK
media=screen href="理解有符號數和無符號數 - Java-Jinguo - JavaEye技術網站.files/blog.css"
type=text/css rel=stylesheet><LINK media=screen
href="理解有符號數和無符號數 - Java-Jinguo - JavaEye技術網站.files/blue.css" type=text/css
rel=stylesheet>
<SCRIPT src="理解有符號數和無符號數 - Java-Jinguo - JavaEye技術網站.files/application.js"
type=text/javascript></SCRIPT>
<LINK media=screen
href="理解有符號數和無符號數 - Java-Jinguo - JavaEye技術網站.files/SyntaxHighlighter.css"
type=text/css rel=stylesheet>
<SCRIPT src="理解有符號數和無符號數 - Java-Jinguo - JavaEye技術網站.files/shCoreCommon.js"
type=text/javascript></SCRIPT>
<STYLE>DIV#main {
BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; WIDTH: 740px; PADDING-TOP: 0px; BACKGROUND-COLOR: transparent; BORDER-RIGHT-WIDTH: 0px
}
</STYLE>
<LINK media=screen href="理解有符號數和無符號數 - Java-Jinguo - JavaEye技術網站.files/ui.css"
type=text/css rel=stylesheet>
<SCRIPT src="理解有符號數和無符號數 - Java-Jinguo - JavaEye技術網站.files/compress.js"
type=text/javascript></SCRIPT>
<META content="MSHTML 6.00.2900.3492" name=GENERATOR></HEAD>
<BODY>
<DIV id=header>
<DIV id=blog_site_nav><A class=homepage href="http://www.javaeye.com/">首頁</A> <A
href="http://www.javaeye.com/news">新聞</A> <A
href="http://www.javaeye.com/forums">論壇</A> <A
href="http://www.javaeye.com/blogs">博客</A> <A
href="http://job.javaeye.com/">招聘</A> <A id=msna onclick="return false;"
href="http://jinguo.javaeye.com/blog/212049#"><U>更多</U> <SMALL>▼</SMALL></A>
<DIV class=quick_menu style="DISPLAY: none"><A
href="http://www.javaeye.com/ask">問答</A> <A
href="http://www.javaeye.com/wiki">知識庫</A> <A
href="http://www.javaeye.com/groups">圈子</A> <A
href="http://www.javaeye.com/search">搜索</A> </DIV></DIV>
<DIV id=user_nav><A class=welcome title=登錄
href="http://jinguo.javaeye.com/login">您還未登錄 !</A> <A style="COLOR: red"
href="http://www.javaeye.com/all">我的應用</A> <A
href="http://jinguo.javaeye.com/login">登錄</A> <A class=nobg
href="http://jinguo.javaeye.com/signup">注冊</A> </DIV></DIV>
<DIV id=page>
<DIV class=clearfix id=branding>
<DIV id=blog_name>
<H1><A href="http://jinguo.javaeye.com/">Java-Jinguo</A></H1></DIV>
<DIV id=blog_preview></DIV>
<DIV id=blog_domain>永久域名 <A
href="http://jinguo.javaeye.com/">http://jinguo.javaeye.com/</A></DIV></DIV>
<DIV class=clearfix id=content>
<DIV id=main>
<DIV class=blog_main>
<DIV id=blog_nav>
<DIV id=pre_next><A class=next
href="http://jinguo.javaeye.com/blog/212590">OpenSessionInView詳解</A> | <A
class=pre href="http://jinguo.javaeye.com/blog/211812">用Java實現幾種常見的排序算法</A>
</DIV></DIV>
<DIV class=blog_title>
<DIV class=date><SPAN class=year>2008</SPAN><SPAN class=sep_year>-</SPAN><SPAN
class=month>07</SPAN><SPAN class=sep_month>-</SPAN><SPAN
class=day>06</SPAN></DIV>
<H3 class="" title=""><A
href="http://jinguo.javaeye.com/blog/212049">理解有符號數和無符號數</A></H3><STRONG>關鍵字:
理解有符號數和無符號數</STRONG> </DIV>
<DIV class=blog_content><BR>理解有符號數和無符號數負數在計算機中如何表示呢? <BR><BR>這一點,你可能聽過兩種不同的回答。
<BR><BR>一種是教科書,它會告訴你:計算機用“補碼”表示負數。可是有關“補碼”的概念一說就得一節課,這一些我們需要在第6章中用一章的篇幅講2進制的一切。再者,用“補碼”表示負數,其實一種公式,公式的作用在于告訴你,想得問題的答案,應該如何計算。卻并沒有告訴你為什么用這個公式就可以和答案?
<BR><BR>另一種是一些程序員告訴你的:用二進制數的最高位表示符號,最高位是0,表示正數,最高位是1,表示負數。這種說法本身沒錯,可是如果沒有下文,那么它就是錯的。至少它不能解釋,為什么字符類型的-1用二進制表示是“1111
1111”(16進制為FF);而不是我們更能理解的“1000 0001”。(為什么說后者更好理解呢?因為既然說最高位是1時表示負數,那1000
0001不是正好是-1嗎?)。 <BR><BR>讓我們從頭說起。 <BR><BR>1、你自已決定是否需要有正負。
<BR><BR>就像我們必須決定某個量使用整數還是實數,使用多大的范圍數一樣,我們必須自已決定某個量是否需要正負。如果這個量不會有負值,那么我們可以定它為帶正負的類型。
<BR><BR>在計算機中,可以區分正負的類型,稱為有符類型,無正負的類型(只有正值),稱為無符類型。
<BR><BR>數值類型分為整型或實型,其中整型又分為無符類型或有符類型,而實型則只有符類型。 <BR><BR>字符類型也分為有符和無符類型。
<BR><BR>比如有兩個量,年齡和庫存,我們可以定前者為無符的字符類型,后者定為有符的整數類型。 <BR><BR>2、使用二制數中的最高位表示正負。
<BR><BR>首先得知道最高位是哪一位?1個字節的類型,如字符類型,最高位是第7位,2個字節的數,最高位是第15位,4個字節的數,最高位是第31位。不同長度的數值類型,其最高位也就不同,但總是最左邊的那位(如下示意)。字符類型固定是1個字節,所以最高位總是第7位。
<BR><BR>(紅色為最高位) <BR><BR>單字節數: 1111 1111 <BR><BR>雙字節數: 1111 1111 1111 1111
<BR><BR>四字節數: 1111 1111 1111 1111 1111 1111 1111 1111 <BR><BR>
<BR><BR>當我們指定一個數量是無符號類型時,那么其最高位的1或0,和其它位一樣,用來表示該數的大小。
<BR><BR>當我們指定一個數量是無符號類型時,此時,最高數稱為“符號位”。為1時,表示該數為負值,為0時表示為正值。 <BR><BR>
<BR><BR>3、無符號數和有符號數的范圍區別。
<BR><BR>無符號數中,所有的位都用于直接表示該值的大小。有符號數中最高位用于表示正負,所以,當為正值時,該數的最大值就會變小。我們舉一個字節的數值對比:
<BR><BR>無符號數: 1111 1111 值:255 1* 27 + 1* 26 + 1* 25 + 1* 24 +
1* 23 + 1* 22 + 1* 21 + 1* 20 <BR><BR>有符號數: 0111 1111
值:127 1* 26 + 1* 25 + 1*
24 + 1* 23 + 1* 22 + 1* 21 + 1* 20 <BR><BR>
<BR><BR>同樣是一個字節,無符號數的最大值是255,而有符號數的最大值是127。原因是有符號數中的最高位被挪去表示符號了。并且,我們知道,最高位的權值也是最高的(對于1字節數來說是2的7次方=128),所以僅僅少于一位,最大值一下子減半。
<BR><BR>不過,有符號數的長處是它可以表示負數。因此,雖然它的在最大值縮水了,卻在負值的方向出現了伸展。我們仍一個字節的數值對比:
<BR><BR>無符號數:
0 ----------------- 255
<BR><BR>有符號數: -128 --------- 0
---------- 127 <BR><BR> <BR><BR>同樣是一個字節,無符號的最小值是 0
,而有符號數的最小值是-128。所以二者能表達的不同的數值的個數都一樣是256個。只不過前者表達的是0到255這256個數,后者表達的是-128到+127這256個數。
<BR><BR>一個有符號的數據類型的最小值是如何計算出來的呢?
<BR><BR>有符號的數據類型的最大值的計算方法完全和無符號一樣,只不過它少了一個最高位(見第3點)。但在負值范圍內,數值的計算方法不能直接使用1* 26 +
1* 25
的公式進行轉換。在計算機中,負數除為最高位為1以外,還采用補碼形式進行表達。所以在計算其值前,需要對補碼進行還原。這些內容我們將在第六章中的二進制知識中統一學習。
<BR><BR>這里,先直觀地看一眼補碼的形式: <BR><BR>以我們原有的數學經驗,在10進制中:1 表示正1,而加上負號:-1 表示和1相對的負值。
<BR><BR>那么,我們會很容易認為在2進制中(1個字節): 0000 0001 表示正1,則高位為1后:1000 0001應該表示-1。
<BR><BR>然而,事實上計算機中的規定有些相反,請看下表: <BR><BR><BR>二進制值(1字節) 十進制值 <BR>1000 0000 -128
<BR>1000 0001 -127 <BR>1000 0010 -126 <BR>1000 0011 -125 <BR>... ... <BR>1111
1110 -2 <BR>1111 1111 -1 <BR><BR>
<BR><BR>首先我們看到,從-1到-128,其二進制的最高位都是1(表中標為紅色),正如我們前面的學。 <BR><BR>然后我們有些奇怪地發現,1000
0000 并沒有拿來表示 -0;而1000 0001也不是拿來直觀地表示-1。事實上,-1 用1111 1111來表示。
<BR><BR>怎么理解這個問題呢?先得問一句是-1大還是-128大? <BR><BR>當然是 -1
大。-1是最大的負整數。以此對應,計算機中無論是字符類型,或者是整數類型,也無論這個整數是幾個字節。它都用全1來表示 -1。比如一個字節的數值中:1111
1111表示-1,那么,1111 1111 - 1 是什么呢?和現實中的計算結果完全一致。1111 1111 - 1 = 1111 1110,而1111
1110就是-2。這樣一直減下去,當減到只剩最高位用于表示符號的1以外,其它低位全為0時,就是最小的負值了,在一字節中,最小的負值是1000
0000,也就是-128。 <BR><BR>我們以-1為例,來看看不同字節數的整數中,如何表達-1這個數: <BR><BR>字節數 二進制值 十進制值
<BR>單字節數 1111 1111 -1 <BR>雙字節數 1111 1111 1111 1111 -1 <BR>四字節數 1111 1111 1111
1111 1111 1111 1111 1111 -1 <BR><BR> <BR><BR>可能有同學這時會混了:為什么 1111 1111
有時表示255,有時又表示-1?所以我再強調一下本節前面所說的第2點:你自已決定一個數是有符號還是無符號的。寫程序時,指定一個量是有符號的,那么當這個量的二進制各位上都是1時,它表示的數就是-1;相反,如果事選聲明這個量是無符號的,此時它表示的就是該量允許的最大值,對于一個字節的數來說,最大值就是255。
<BR><BR><BR>原碼、反碼、補碼 <BR><BR>我們已經知道計算機中,所有數據最終都是使用二進制數表達。
<BR><BR>我們也已經學會如何將一個10進制數如何轉換為二進制數。 <BR><BR>不過,我們仍然沒有學習一個負數如何用二進制表達。 <BR><BR>
<BR><BR>比如,假設有一 int 類型的數,值為5,那么,我們知道它在計算機中表示為: <BR><BR>00000000 00000000
00000000 00000101 <BR><BR>5轉換成二制是101,不過int類型的數占用4字節(32位),所以前面填了一堆0。
<BR><BR>現在想知道,-5在計算機中如何表示? <BR><BR> <BR><BR>在計算機中,負數以其正值的補碼形式表達。
<BR><BR>什么叫補碼呢?這得從原碼,反碼說起。 <BR><BR> <BR><BR>原碼:一個整數,按照絕對值大小轉換成的二進制數,稱為原碼。
<BR><BR>比如 00000000 00000000 00000000 00000101 是 5的 原碼。 <BR><BR>
<BR><BR>反碼:將二進制數按位取反,所得的新二進制數稱為原二進制數的反碼。 <BR><BR>取反操作指:原為1,得0;原為0,得1。(1變0; 0變1)
<BR><BR>比如:將00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111
11111010。 <BR><BR>稱:11111111 11111111 11111111 11111010 是 00000000 00000000
00000000 00000101 的反碼。 <BR><BR>反碼是相互的,所以也可稱: <BR><BR>11111111 11111111 11111111
11111010 和 00000000 00000000 00000000 00000101 互為反碼。 <BR><BR>
<BR><BR>補碼:反碼加1稱為補碼。 <BR><BR>也就是說,要得到一個數的補碼,先得到反碼,然后將反碼加上1,所得數稱為補碼。
<BR><BR>比如:00000000 00000000 00000000 00000101 的反碼是:11111111 11111111 11111111
11111010。 <BR><BR>那么,補碼為: <BR><BR>11111111 11111111 11111111 11111010 + 1 =
11111111 11111111 11111111 11111011 <BR><BR> <BR><BR>所以,-5 在計算機中表達為:11111111
11111111 11111111 11111011。轉換為十六進制:0xFFFFFFFB。 <BR><BR>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -