摘要:問題描述遇到一個題目經過強制類型轉換以后,變量,的值分別為多少答案是這涉及到的,打算借此稍稍研究一下。分為兩種,一是擴展型基本數(shù)據(jù)類型轉換,二是窄化型基本數(shù)據(jù)類型轉換。需要注意的是是有可能丟失數(shù)值的整體信息以及損失精度和范圍的。
問題描述
遇到一個題目:
經過強制類型轉換以后,變量a,b的值分別為多少?
short a = 128;
byte b = (byte) a;
a = ?, b = ?
答案是:a = 128, b = -128
這涉及到 Java primitive type 的 conversion,打算借此稍稍研究一下。
分析過程下面分析中會涉及到一些與題目無關的細節(jié),想直接看題目解答的請?zhí)?"題目中的數(shù)值在內存中的表示"
明確 Java 中的 ConversionJava 的 conversion 有多種,這里我們只討論 primitive conversion。
primitive conversion 分為兩種,一是 Widening Primitive Conversion(擴展型基本數(shù)據(jù)類型轉換),二是 Narrowing Primitive Conversion(窄化型基本數(shù)據(jù)類型轉換)。
ps: 翻譯成中文還是感覺怪怪的,下面還是用英文表示吧。
JLS 定義了 19 種 widening pc,簡單來說,就是位數(shù)低的向高的轉換,如下
byte to short, int, long, float, or double
short to int, long, float, or double
char to int, long, float, or double
int to long, float, or double
long to float or double
float to double
widening pc 不會丟失數(shù)值的整體大小信息
這個問題涉及到的 int -> short 和 short -> byte 的轉換就包含在 JLS 定義的 22 種 narrowing pc 之中。
short to byte or char
char to byte or short
int to byte, short, or char
long to byte, short, char, or int
float to byte, short, char, int, or long
double to byte, short, char, int, long, or float
需要注意的是 narrowing pc 是有可能丟失數(shù)值的整體信息以及損失精度和范圍的。
可能有人會注意到,上面的 widening pc 和 narrowing pc 都沒有包含 byte -> char 的轉換
Chapter 5. Conversions and Promotions
The following conversion combines both widening and narrowing primitive conversions:
byte to char
First, the byte is converted to an int via widening primitive conversion (§5.1.2), and then the resulting int is converted to a char by narrowing primitive conversion (§5.1.3).
這是因為這是一種特殊地、同時結合了 widening pc 和 narrowing pc 的轉換,byte 會先轉換成 int(widening pc),然后將這個 int 結果轉換成 char(narrowing pc)。
具體分析那么我們還是回到這個問題
short a = 128;
byte b = (byte) a;
首先,在 Java 中,整數(shù)默認為 int 類型,也就是說,在 short a = 128; 中,會發(fā)生 int -> short 的 narrowing pc,是有可能損失精度的,由于 int 是高位(32位),short 是低位(16位),所以在轉換時會 truncate。同樣,對于 byte b = (byte) a; 也有可能因為 truncate 而損失精度。
先回顧原碼、反碼、補碼的概念在 Java 中數(shù)值是用補碼表示的,在這里回顧一下原碼、反碼、補碼的概念(以 3 為例吧):
原碼(第一個為符號位,1 表示負數(shù),0 表示正數(shù))
3 的原碼:0000 0011
-3 的原碼:1000 0011
反碼(就是反過來,注意符號位不變):
3 的反碼:1111 1100
-3 的反碼:1111 1100
補碼(正數(shù)的補碼 = 原碼,負數(shù)的補碼 = 反碼 + 1)
3 的補碼:0000 0011
-3 的補碼:1111 1101
題目中的數(shù)值在內存中的表示二進制表示:
int a = 128 00000000 00000000 10000000 00000000
short a = 128 00000000 10000000 (強轉后前面 16 位被截斷)
可以看出來,a 的值輸出應該還是 128
那么對于 byte b = (byte) a;
二進制表示:
short a = 128 00000000 10000000
byte b = 128 10000000 (強轉后前面 8 位被截斷)
但是,輸出的 b 的值為什么不是 128 而是 -128 呢
Primitive Data Types (The Java? Tutorials > Learning the Java Language > Language Basics)
byte: The byte data type is an 8-bit signed two"s complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place of int where their limits help to clarify your code; the fact that a variable"s range is limited can serve as a form of documentation.
這是因為 byte 是一個 8 位有符號二進制補碼整數(shù),它包含的值的范圍是 [-128, 127],因此 byte 類型的值是無法表示 128 的
那么在發(fā)生截斷后,1000 0000 表示的就是一個補碼,從這個補碼可以看出來它的原碼肯定是一個負數(shù),那么我們根據(jù)這個補碼反推得到它的反碼:1111 1111,從而得到它的原碼:1000 0000,可以看出這個值就是 -0,但是在我們的生活中是沒有 -0 的,所以在計算機中就把它識別成 -128,因此這就是為什么 b 的值的輸出是 -128 的原因。
ps: 關于 -0 對應于 -128 的具體解釋,我懶得寫了,因為感覺取決于個人的理解,不想細究,如果有人還有疑問,可以看看這個人的解釋 byte類型取值范圍為什么是127到-128? - 知乎
那么到這里,問題就基本解釋清楚了,感覺自己還是很啰嗦,不過其實是為了回顧一些基礎的知識,也希望對其他人有所幫助啦~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://www.ezyhdfw.cn/yun/69394.html
摘要:中用補碼形式表示第一位正負位,表示負,表示正。原碼一個數(shù)的二進制表示。的補碼是的補碼是占個字節(jié),位占個字節(jié),位所以強轉時會截斷。 showImg(https://segmentfault.com/img/bVbsydY?w=993&h=471); 1、Java中用補碼形式表示2、第一位正負位,1表示負,0表示正。3、原碼:一個數(shù)的二進制表示。 3的原碼0000...
摘要:基本類型的類型轉換和強制類型轉換一的變量類型分為種。目錄基本類型的類型轉換隱式類型轉換基本類型的強制類型轉換基本類型的類型轉換隱式類型轉換基本類型的類型轉換是通過擴展轉換的規(guī)則完成的。 基本類型的類型轉換和強制類型轉換(一) Java的變量類型分為2種?;绢愋停ㄔ碱愋停┖鸵妙愋??;绢愋桶ㄒ韵掳朔N類型:boolean、 char、byte、short、int、long、floa...
摘要:在改進前使用數(shù)組的一個缺點是必須聲明數(shù)組的大小,所以棧有確定的容量。待解決的問題建立一個能夠增長或者縮短到任意大小的棧。下邊的圖是觀察時間開銷的另一種方式,表示了入棧操作需要訪問數(shù)組的次數(shù)。 前言 上一篇:算法分析下一篇:基本排序 本篇內容主要是棧,隊列 (和包)的基本數(shù)據(jù)類型和數(shù)據(jù)結構文章里頭所有的對數(shù)函數(shù)都是以 2 為底關于性能分析,可能還是需要一些數(shù)學知識,有時間可以回一下在很多...
摘要:雖然定義了這種數(shù)據(jù)類型,但是只對它提供了非常有限的支持。數(shù)據(jù)類型的自動轉換規(guī)律數(shù)據(jù)范圍小的類型與數(shù)據(jù)范圍大的類型進行數(shù)學計算的時候,自動向數(shù)據(jù)范圍大的類型轉換數(shù)據(jù)范圍大的類型想要變?yōu)閿?shù)據(jù)范圍小的類型,必須采用強制類型轉轉。 java數(shù)據(jù)類型 java一共分為兩大類數(shù)據(jù): 基本數(shù)據(jù)類型(值類型) 引用數(shù)據(jù)類型 基本數(shù)據(jù)類型 基本數(shù)據(jù)類型一共有八種,分為:數(shù)值型: 整型: byte、s...
閱讀 4040·2021-11-22 13:53
閱讀 1783·2021-08-25 09:39
閱讀 2495·2019-08-29 18:36
閱讀 1545·2019-08-26 13:35
閱讀 1278·2019-08-26 11:57
閱讀 1767·2019-08-23 15:57
閱讀 880·2019-08-23 14:55
閱讀 1225·2019-08-23 14:51