java中int轉(zhuǎn)string與string轉(zhuǎn)int的效率對(duì)比
int轉(zhuǎn)string與string轉(zhuǎn)int的效率對(duì)比
string轉(zhuǎn)int,兩種方法
Interger.parseInt(String) Interger.valueOf(String).intValue()
第二種方法可以去看源碼,實(shí)現(xiàn)了第一種方法。

注釋大概就是這樣的意思
/**
? ? ? *返回一個(gè)包含整數(shù)的對(duì)象
? ? ? *指定的{@ String String}的值。 這個(gè)說(shuō)法是
? ? ? *被解釋為表示一個(gè)有符號(hào)的十進(jìn)制整數(shù)
? ? ? *就好像這個(gè)論據(jù)是給予{@link的
? ? ? * #parseInt(java.lang.String)}方法。 結(jié)果是一個(gè)
? ? ? 表示整數(shù)值的整數(shù)對(duì)象
? ? ? *由字符串指定。
? ? ?*
? ? ? 換句話說(shuō),這個(gè)方法返回一個(gè){@code Integer}
? ? ? *對(duì)象等于以下值:
? ? ?*
? ? ? * <blockquote>
? ? ? * {@code new Integer(Integer.parseInt(s))}
? ? ? * </ blockquote>
? ? ?*
? ? ? * @param是要解析的字符串。
? ? ? * @返回一個(gè)保存值的{整數(shù)}對(duì)象
? ? ? *由字符串參數(shù)表示。
? ? ? * @exception NumberFormatException如果字符串不能被解析
? ? ? *作為一個(gè)整數(shù)。
? ? ?*/在valueOf()里面實(shí)現(xiàn)了parseInt()方法。時(shí)間對(duì)比第二種比第一種要快了很多。
?Integer.parseInt(str) : 21 ?Integer.valueOf(str).intValue() : 14
int 轉(zhuǎn)string一般用三種方法
- 第一種:number + ""
- 第二種:string.valueOf()
- 第三種:.toString()
- 先說(shuō)第一種,簡(jiǎn)單粗暴。
- 第二種方法:底層使用的依舊是.toString()方法
- 第三種就是toString()
上代碼。
int num = 888888;
//(1)num + ""
long start = System.currentTimeMillis();//得到開(kāi)始運(yùn)行時(shí)系統(tǒng)時(shí)間
for(int i=0; i<100000; i++){
String str = num + "";
}
long end = System.currentTimeMillis();//得到結(jié)束運(yùn)行時(shí)系統(tǒng)時(shí)間
System.out.println("num + \"\" : " + (end - start));
//(2)String.valueOf(num)
start = System.currentTimeMillis();
for(int i=0; i<100000; i++){
String str = String.valueOf(num);
}
end = System.currentTimeMillis();
System.out.println("String.valueOf(num) : " + (end - start));
//(3)Integer.toString(num)
start = System.currentTimeMillis();
for(int i=0; i<100000; i++){
String str = Integer.toString(num);
}
end = System.currentTimeMillis();
System.out.println("Integer.toString(num) : " + (end - start));結(jié)果就是
num + "" : 82
String.valueOf(num) : 32
Integer.toString(num) : 9
經(jīng)過(guò)多次的反復(fù)測(cè)試,toString()是最快的,num+""是最慢的,在使用String.valueOf()中源碼是這樣的。
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}也就是說(shuō)在使用的時(shí)候,不用去判斷所傳的對(duì)象是否為null,但是尤其注意,如果傳的為空,返回來(lái)的是一個(gè)為null的字符串而不是null值,這個(gè)地方需要謹(jǐn)記。
string轉(zhuǎn)int問(wèn)題分析
相信很多同學(xué)在面試時(shí)都遇到過(guò)這樣一個(gè)問(wèn)題,要求封裝一個(gè)函數(shù),將String類(lèi)型轉(zhuǎn)換為int類(lèi)型。這個(gè)看似簡(jiǎn)單的問(wèn)題其實(shí)隱藏著很多細(xì)節(jié),要想真正封裝好這個(gè)函數(shù)并不容易。面試官要考察的其實(shí)并不是算法本身的難度,這個(gè)問(wèn)題的算法其實(shí)沒(méi)有什么難度可言,主要要考察的是程序員寫(xiě)代碼的仔細(xì)程度,考慮問(wèn)題是否全面,也就是說(shuō),我們要盡可能的讓代碼具有魯棒性。下面我們一步步的分析這個(gè)問(wèn)題中隱藏的細(xì)節(jié)。
分析一波
首先我們不考慮任何的異常處理,假設(shè)函數(shù)的調(diào)用者傳入的數(shù)據(jù)都是正確的,很容易就可以寫(xiě)出下面的代碼:
? ? public int strToInt(String str) {
? ? ? ? int number = 0;
? ? ? ? for (int i=0; i<str.length(); i++) {
? ? ? ? ? ? number *= 10;
? ? ? ? ? ? number += (str.charAt(i) - '0');
? ? ? ? }
? ? ? ? return number;
? ? }上面的代碼將遍歷字符串的每一位字符,并將其轉(zhuǎn)換為對(duì)應(yīng)的整數(shù),然后將其一一融入到整形數(shù)據(jù)number中。
如果你給面試官提交的是這樣一份代碼,結(jié)果肯定不會(huì)滿意。因?yàn)槟銢](méi)有考慮到程序的魯棒性,我們封裝的函數(shù)相當(dāng)于API接口,是提供給所有開(kāi)發(fā)者調(diào)用的,難免其他開(kāi)發(fā)者不會(huì)傳入一些奇怪的參數(shù),而這段代碼對(duì)異常參數(shù)沒(méi)有做任何處理,一旦傳入異常參數(shù),程序?qū)⒅苯颖罎?。下面我們一步步?lái)完善這個(gè)函數(shù),提高其魯棒性。
1、針對(duì)傳入的字符串為空對(duì)象或者字符串為空的字符串
? ? public int strToInt(String str) throws NumberFormatException{
? ? ? ? if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對(duì)象或者傳入的字符串為空字符串,則拋出異常
? ? ? ? ? ? throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類(lèi),當(dāng)然我們也可以自己封裝異常類(lèi),面試官要考察的不是對(duì)異常類(lèi)的封裝,而是你要知道要處理異常情況
? ? ? ? }
? ? ? ? int number = 0;
? ? ? ? for (int i=0; i<str.length(); i++) {
? ? ? ? ? ? number *= 10;
? ? ? ? ? ? number += (str.charAt(i) - '0');
? ? ? ? }
? ? ? ? return number;
? ? }首先我們字符串是否為空或者是否為空的字符串,如果是,則直接拋出異常,這里我們使用的是Java封裝好的異常類(lèi)NumberFormatException,當(dāng)然我們也可以自己封裝異常類(lèi),面試官要考察的不是對(duì)異常類(lèi)的封裝,而是你要知道要處理異常情況。
2、針對(duì)符號(hào)位的處理
這個(gè)我們最好提前問(wèn)一下面試官,有沒(méi)有可能傳入的是負(fù)數(shù),當(dāng)為正數(shù)時(shí),是否允許帶符號(hào)位,如果是的話,我們就要針對(duì)符號(hào)位進(jìn)行處理,負(fù)數(shù)的第一個(gè)字符是“-”,我們只要判斷第一個(gè)字符是否為“-”就可以知道傳入的是否為負(fù)數(shù)了,如果正數(shù)允許帶符號(hào)位,那邊第一個(gè)字符有可能是“+”,我們也要做對(duì)應(yīng)的處理:
? ? public int strToInt(String str) throws NumberFormatException{
? ? ? ? if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對(duì)象或者傳入的字符串為空字符串,則拋出異常
? ? ? ? ? ? throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類(lèi),當(dāng)然我們也可以自己封裝異常類(lèi),面試官要考察的不是對(duì)異常類(lèi)的封裝,而是你要知道要處理異常情況
? ? ? ? }
? ? ? ? boolean negative = false; // negative為true表示是負(fù)數(shù),反之為正數(shù)
? ? ? ? int pos = 0;
? ? ? ? if (str.charAt(0) == '-') { // 如果為負(fù)數(shù)
? ? ? ? ? ? negative = true;
? ? ? ? ? ? pos++; // 調(diào)過(guò)第一位符號(hào)位
? ? ? ? } else if (str.charAt(0) == '+') {
? ? ? ? ? ? pos++; // 調(diào)過(guò)第一位符號(hào)位
? ? ? ? }
? ? ? ? int number = 0;
? ? ? ? while (pos < str.length()) {
? ? ? ? ? ? number *= 10;
? ? ? ? ? ? number += (str.charAt(pos) - '0');
? ? ? ? ? ? pos++;
? ? ? ? }?
? ? ? ? return negative ? -number : number; // 如果為負(fù)數(shù)則返回對(duì)應(yīng)的負(fù)數(shù)
? ? }3、針對(duì)錯(cuò)誤字符的處理
函數(shù)的調(diào)用者可能會(huì)傳入一下亂七八糟的字符串,比如“abc23123”,針對(duì)這種情況我們也要做對(duì)應(yīng)的處理,應(yīng)該給調(diào)用者拋出一個(gè)異常,告知其傳入的字符串是非法字符串:
? ? public int strToInt(String str) throws NumberFormatException{
? ? ? ? if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對(duì)象或者傳入的字符串為空字符串,則拋出異常
? ? ? ? ? ? throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類(lèi),當(dāng)然我們也可以自己封裝異常類(lèi),面試官要考察的不是對(duì)異常類(lèi)的封裝,而是你要知道要處理異常情況
? ? ? ? }
? ? ? ? boolean negative = false; // negative為true表示是負(fù)數(shù),反之為正數(shù)
? ? ? ? int pos = 0;
? ? ? ? if (str.charAt(0) == '-') { // 如果為負(fù)數(shù)
? ? ? ? ? ? negative = true;
? ? ? ? ? ? pos++; // 調(diào)過(guò)第一位符號(hào)位
? ? ? ? } else if (str.charAt(0) == '+') {
? ? ? ? ? ? pos++; // 調(diào)過(guò)第一位符號(hào)位
? ? ? ? }
? ? ? ? int number = 0;
? ? ? ? while (pos < str.length()) {
? ? ? ? ? ? if (str.charAt(pos) >= '0' && str.charAt(pos) <= '9') { // 只有字符在'0'到'9'的范圍內(nèi),才算正確的字符
? ? ? ? ? ? ? ? number *= 10;
? ? ? ? ? ? ? ? number += (str.charAt(pos) - '0');
? ? ? ? ? ? ? ? pos++;?
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? throw new NumberFormatException("invalid string"); // 當(dāng)字符是其他字符時(shí),拋出異常告知調(diào)用者傳入的字符串錯(cuò)誤
? ? ? ? ? ? }
? ? ? ? }?
? ? ? ? return negative ? -number : number; // 如果為負(fù)數(shù)則返回對(duì)應(yīng)的負(fù)數(shù)
? ? }4、針對(duì)整形數(shù)據(jù)超出范圍的處理
調(diào)用者傳入的字符串可能是一個(gè)很長(zhǎng)的字符串,轉(zhuǎn)換為整數(shù)可能超出了整數(shù)的存儲(chǔ)范圍,比如“12345678674324334”,在這種情況下,我們要拋出一個(gè)異常告知調(diào)用者傳入的字符串超出了整形的范圍:
? ? public int strToInt(String str) throws NumberFormatException{
? ? ? ? if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對(duì)象或者傳入的字符串為空字符串,則拋出異常
? ? ? ? ? ? throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類(lèi),當(dāng)然我們也可以自己封裝異常類(lèi),面試官要考察的不是對(duì)異常類(lèi)的封裝,而是你要知道要處理異常情況
? ? ? ? }
? ? ? ? boolean negative = false; // negative為true表示是負(fù)數(shù),反之為正數(shù)
? ? ? ? int pos = 0;
? ? ? ? if (str.charAt(0) == '-') { // 如果為負(fù)數(shù)
? ? ? ? ? ? negative = true;
? ? ? ? ? ? pos++; // 調(diào)過(guò)第一位符號(hào)位
? ? ? ? } else if (str.charAt(0) == '+') {
? ? ? ? ? ? pos++; // 調(diào)過(guò)第一位符號(hào)位
? ? ? ? }
? ? ? ? int limit = negative ? (-Integer.MIN_VALUE) : Integer.MAX_VALUE;
? ? ? ? int mult = limit / 10; // 記錄最大數(shù)/10,讓number和這個(gè)數(shù)比較,如果大于它,則number * 10肯定也就大于最大數(shù)
? ? ? ? int number = 0;
? ? ? ? while (pos < str.length()) {
? ? ? ? ? ? if (str.charAt(pos) >= '0' && str.charAt(pos) <= '9') { // 只有字符在'0'到'9'的范圍內(nèi),才算正確的字符
? ? ? ? ? ? ? ? if (number > mult) {// 讓number和mult比較,如果大于它,則number * 10肯定也就大于最大數(shù)
? ? ? ? ? ? ? ? ? ? throw new NumberFormatException("input string beyond int size");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? number *= 10;
? ? ? ? ? ? ? ? int digit = str.charAt(pos) - '0';
? ? ? ? ? ? ? ? if (number > limit - digit) { // 這里不能用number + digit > limit來(lái)判斷,因?yàn)閚umber + digit可能超出整數(shù)的存儲(chǔ)范圍,相加后的數(shù)可能是一個(gè)負(fù)數(shù),但是limit - digit肯定不會(huì)超出
? ? ? ? ? ? ? ? ? ? throw new NumberFormatException("input string beyond int size");
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? number += digit;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? pos++;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? throw new NumberFormatException("invalid string"); // 當(dāng)字符是其他字符時(shí),拋出異常告知調(diào)用者傳入的字符串錯(cuò)誤
? ? ? ? ? ? }
? ? ? ? }?
? ? ? ? return negative ? -number : number; // 如果為負(fù)數(shù)則返回對(duì)應(yīng)的負(fù)數(shù)
? ? }上面的代碼中,我們判斷number是否會(huì)超出最大整數(shù)時(shí)首先是先讓其(最大整數(shù)/10)的值比較,而不是讓其乘以10與最大整數(shù)比較,這是因?yàn)閚umber * 10如果超出了整數(shù)范圍,則會(huì)造成數(shù)據(jù)溢出,其得到的值可能是一個(gè)負(fù)數(shù),而(最大整數(shù)/10)的值是不會(huì)數(shù)據(jù)溢出的,這也是一個(gè)小細(xì)節(jié)??赡苣阋詾檫@樣這個(gè)函數(shù)就完美了,但是現(xiàn)在我要告訴你,上面的寫(xiě)法是錯(cuò)誤的。
為什么呢?這要從整數(shù)的范圍說(shuō)起,整數(shù)的取值范圍是(-2^31)至(2^31 - 1),從絕對(duì)值的角度看,最小負(fù)數(shù)相比于最大正數(shù)大1。所以上面代碼中(-Integer.MIN_VALUE)會(huì)超出整形的范圍,造成數(shù)據(jù)溢出,也就是說(shuō)上面的代碼對(duì)負(fù)數(shù)最小范圍的限制的處理是錯(cuò)誤的。那么怎么解決這個(gè)問(wèn)題呢?
我們換個(gè)角度思考,最小負(fù)數(shù)的絕對(duì)值比最大正數(shù)的絕對(duì)值大1,那(-Integer.MAX_VALUE)的值肯定不會(huì)超出整數(shù)的范圍,我們現(xiàn)在的程序是以正數(shù)的方式處理,如果反過(guò)來(lái)已負(fù)數(shù)的方式處理,問(wèn)題不就解決了嗎?修改代碼如下:
? ? public int strToInt(String str) throws NumberFormatException{
? ? ? ? if (str == null || str.contentEquals("")) { // 如果傳入的字符串為空對(duì)象或者傳入的字符串為空字符串,則拋出異常
? ? ? ? ? ? throw new NumberFormatException("null or empty string"); // 這里直接利用java封裝好的異常類(lèi),當(dāng)然我們也可以自己封裝異常類(lèi),面試官要考察的不是對(duì)異常類(lèi)的封裝,而是你要知道要處理異常情況
? ? ? ? }
? ? ? ? boolean negative = false; // negative為true表示是負(fù)數(shù),反之為正數(shù)
? ? ? ? int pos = 0;
? ? ? ? if (str.charAt(0) == '-') { // 如果為負(fù)數(shù)
? ? ? ? ? ? negative = true;
? ? ? ? ? ? pos++; // 調(diào)過(guò)第一位符號(hào)位
? ? ? ? } else if (str.charAt(0) == '+') {
? ? ? ? ? ? pos++; // 調(diào)過(guò)第一位符號(hào)位
? ? ? ? }
? ? ? ? int limit = negative ? Integer.MIN_VALUE : (-Integer.MAX_VALUE);
? ? ? ? int mult = limit / 10;
? ? ? ? int number = 0;
? ? ? ? while (pos < str.length()) {
? ? ? ? ? ? if (str.charAt(pos) >= '0' && str.charAt(pos) <= '9') { // 只有字符在'0'到'9'的范圍內(nèi),才算正確的字符
? ? ? ? ? ? ? ? if (number < mult) {
? ? ? ? ? ? ? ? ? ? throw new NumberFormatException("input string beyond int size");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? number *= 10;
? ? ? ? ? ? ? ? int digit = str.charAt(pos) - '0';
? ? ? ? ? ? ? ? if (number < limit + digit) {
? ? ? ? ? ? ? ? ? ? throw new NumberFormatException("input string beyond int size");
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? number -= digit;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? pos++;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? throw new NumberFormatException("invalid string"); // 當(dāng)字符是其他字符時(shí),拋出異常告知調(diào)用者傳入的字符串錯(cuò)誤
? ? ? ? ? ? }
? ? ? ? }?
? ? ? ? return negative ? number : -number;
? ? }OK,現(xiàn)在我們把能夠想到的異常情況處理了。再來(lái)考慮一個(gè)問(wèn)題,為什么整形數(shù)據(jù)的范圍是(-2^31)至(2^31 - 1),最小負(fù)數(shù)的絕對(duì)值比最大正數(shù)的絕對(duì)值要大1呢?
5、int數(shù)據(jù)范圍的討論
我們知道,一個(gè)int類(lèi)型占四個(gè)字節(jié),也就是32位,其中第一位是符號(hào)位,符號(hào)位為0表示正數(shù),為1表示負(fù)數(shù),其余31位表示數(shù)值。正常來(lái)說(shuō)int類(lèi)型的數(shù)據(jù)范圍應(yīng)該是(-2^31-1)到(2^31-1),為什么負(fù)數(shù)會(huì)多一位呢?
我們首先看一下Java代碼中對(duì)Integer.MAX_VALUE和Integer.MIN_VALUE的定義:
? ? /**
? ? ?* A constant holding the minimum value an {@code int} can
? ? ?* have, -2<sup>31</sup>.
? ? ?*/
? ? public static final int ? MIN_VALUE = 0x80000000;
?
? ? /**
? ? ?* A constant holding the maximum value an {@code int} can
? ? ?* have, 2<sup>31</sup>-1.
? ? ?*/
? ? public static final int ? MAX_VALUE = 0x7fffffff;原碼、反碼、補(bǔ)碼
我們知道,在計(jì)算機(jī)中,數(shù)據(jù)都是以二進(jìn)制的形式存儲(chǔ)的,比如,數(shù)字10,其二進(jìn)制形式就是1010。
一個(gè)字節(jié)有8位,每位可以存儲(chǔ)一個(gè)01字符,byte類(lèi)型占1個(gè)字節(jié),也就是8位,其中,最高位是符號(hào)位,用來(lái)表示數(shù)值是正數(shù)還是負(fù)數(shù),符號(hào)位為0表示正數(shù),符號(hào)位為1表示負(fù)數(shù)。我們先來(lái)看一下原碼、反碼、補(bǔ)碼的定義:
- 原碼:符號(hào)位加上真值的絕對(duì)值, 即用第一位表示符號(hào), 其余位表示值。
- 反碼:正數(shù)的反碼是其本身;負(fù)數(shù)的反碼是在其原碼的基礎(chǔ)上, 符號(hào)位不變,其余各個(gè)位取反。
- 補(bǔ)碼:補(bǔ)碼的表示方法是:正數(shù)的補(bǔ)碼就是其本身;負(fù)數(shù)的補(bǔ)碼是在其原碼的基礎(chǔ)上, 符號(hào)位不變, 其余各位取反, 最后+1。 (即在反碼的基礎(chǔ)上+1)
正數(shù)的原碼、反碼、補(bǔ)碼都是其本身;負(fù)數(shù)的反碼是在其原碼的基礎(chǔ)上,符號(hào)位不變,其余個(gè)位取反,負(fù)數(shù)的補(bǔ)碼是其反碼的基礎(chǔ)上+1。
舉例說(shuō)明(下面都以byte類(lèi)型進(jìn)行舉例):
| 數(shù)據(jù) | 原碼 | 反碼 | 補(bǔ)碼 |
| 10 | 00001010 | 00001010 | 00001010 |
| -10 | 10001010 | 11110101 | 11110110 |
計(jì)算機(jī)中,數(shù)據(jù)都是以補(bǔ)碼的形式存儲(chǔ)的。為什么要以補(bǔ)碼的形式存儲(chǔ)呢?有兩個(gè)原因:
1、如果數(shù)值以補(bǔ)碼的形式保存,對(duì)一個(gè)數(shù)進(jìn)行求補(bǔ)運(yùn)算,可以得到其相反值
求補(bǔ)運(yùn)算:將一個(gè)數(shù)(包括正數(shù)和負(fù)數(shù))所有二進(jìn)制位(包括符號(hào)位和數(shù)值位)取反,然后在最低位加上1。
為什么對(duì)一個(gè)數(shù)進(jìn)行求補(bǔ)運(yùn)算,可以得到其相反值呢?我們先來(lái)分析一下求補(bǔ)運(yùn)算的定義,現(xiàn)將所有的二進(jìn)制取反,然后+1,首先一個(gè)數(shù)和它所有位取反得到的數(shù)相加,其結(jié)果肯定是11111111,這是因?yàn)樗鼈兠恳晃欢疾灰粯?,然后將結(jié)果+1,即11111111 + 1,結(jié)果是1 00000000,最高位的1已經(jīng)溢出,換種方式說(shuō),如果以f(n)表示對(duì)n進(jìn)行求補(bǔ)運(yùn)算,那么對(duì)于任意的范圍內(nèi)的數(shù),可以得到:
n + f(n) = 1 00000000
即
f(n) = 1 00000000 - n
而對(duì)于一個(gè)正數(shù)來(lái)說(shuō),對(duì)其進(jìn)行求補(bǔ)運(yùn)算其實(shí)得到的就是它的相反數(shù)的補(bǔ)碼(負(fù)數(shù)的補(bǔ)碼符號(hào)位保持不變,其他為全部取反再+1,因?yàn)檎龜?shù)和負(fù)數(shù)的符號(hào)位本來(lái)就不一樣,所以對(duì)一個(gè)正數(shù)進(jìn)行求補(bǔ)其實(shí)得到的就是它的相反數(shù)的補(bǔ)碼)。
那么對(duì)于一個(gè)負(fù)數(shù)來(lái)說(shuō)呢?對(duì)其進(jìn)行求補(bǔ)運(yùn)算是否能夠得到其對(duì)應(yīng)的正數(shù)的補(bǔ)碼呢?
假設(shè)n>0,根據(jù)上面可知:
f(n) = 1 00000000 - n
對(duì)f(n)進(jìn)行求補(bǔ)運(yùn)算,有:
f(f(n)) = f(1 00000000 - n) = 1 00000000 - (1 00000000 - n) = n
其中,1 00000000 - n表示n對(duì)應(yīng)負(fù)數(shù)的補(bǔ)碼,對(duì)其進(jìn)行求補(bǔ)運(yùn)算得到的就是n,正數(shù)的補(bǔ)碼就是其原碼。
由上可知:如果數(shù)值以補(bǔ)碼的形式保存,對(duì)一個(gè)數(shù)進(jìn)行求補(bǔ)運(yùn)算,可以得到其相反值,即:f(n) = -n
2、方便減法運(yùn)算
如果數(shù)值以補(bǔ)碼的方式存儲(chǔ),可以將減法變?yōu)榧臃?,省去了減法器,通過(guò)上面的推導(dǎo),如果數(shù)據(jù)以補(bǔ)碼的方式存儲(chǔ),以f(n)表示對(duì)n進(jìn)行求補(bǔ)運(yùn)算,可以得到:
f(n) = -n
那么現(xiàn)在我們需要計(jì)算m - n,應(yīng)該要怎么計(jì)算呢?如果以補(bǔ)碼的方式存儲(chǔ),那么就有:
m - n = m + (-n) = m + f(n)
也就是說(shuō),減去一個(gè)數(shù)只需要加上對(duì)其進(jìn)行求補(bǔ)運(yùn)算后得到的值即可。
3、使用補(bǔ)碼存儲(chǔ)數(shù)據(jù),可以對(duì)任意的兩個(gè)數(shù)直接進(jìn)行相加運(yùn)算,不用考慮符號(hào)位
4、通過(guò)補(bǔ)碼形式存儲(chǔ),規(guī)定10000000對(duì)應(yīng)的負(fù)數(shù)的最小值,也就是-128。
由上面可知,如果是byte類(lèi)型,數(shù)據(jù)范圍應(yīng)該為[-128,127],最小負(fù)數(shù)要比最大正數(shù)多一位。
小結(jié)一下
我們?cè)趯?xiě)代碼時(shí),不能僅僅注意代碼的功能,還要考慮到代碼的魯棒性,比如參數(shù)的正確性、參數(shù)的范圍以及異常情況的處理等等。只有這樣,我們寫(xiě)出的程序才能更加健壯,這也是一個(gè)優(yōu)秀開(kāi)發(fā)者的基本素質(zhì)。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot啟動(dòng)后和停止前執(zhí)行方法示例詳解
這篇文章主要介紹了springboot啟動(dòng)后和停止前執(zhí)行方法,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
【IntelliJ IDEA】Maven構(gòu)建自己的第一個(gè)Java后臺(tái)的方法
本篇文章主要介紹了Maven構(gòu)建自己的第一個(gè)Java后臺(tái)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Mybatis批量插入更新xml方式和注解方式的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于Mybatis批量插入更新xml方式和注解方式的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Mybatis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12

