Java中不一致的操作会扩大规则
總覽
當(dāng)您在Java中執(zhí)行一元或二進(jìn)制操作時(shí),標(biāo)準(zhǔn)行為是使用最寬的操作數(shù)(或?qū)yte , short和char使用更寬的操作數(shù))。 這很容易理解,但是如果考慮最佳類型可能會(huì)造成混淆。
乘法
當(dāng)執(zhí)行乘法運(yùn)算時(shí),您得到的數(shù)值通常比單個(gè)數(shù)值大得多。 即| a * b | >> | a | 和| a * b | >> | b | 通常是這種情況。 對于小型字體,這可以按預(yù)期工作。
考慮以下程序:
public static void main(String[] args) throws IOException {System.out.println(is(Byte.MAX_VALUE * Byte.MAX_VALUE));System.out.println(is(Short.MAX_VALUE * Short.MAX_VALUE));System.out.println(is(Character.MAX_VALUE * Character.MAX_VALUE));System.out.println(is(Integer.MAX_VALUE * Integer.MAX_VALUE));System.out.println(is(Long.MAX_VALUE * Long.MAX_VALUE)); }static String is(byte b) {return "byte: " + b; }static String is(char ch) {return "char: " + ch; }static String is(short i) {return "short: " + i; }static String is(int i) {return "int: " + i; }static String is(long l) {return "long: " + l; }打印:
int: 16129 int: 1073676289 int: -131071 int: 1 long: 1只有byte * byte和short * short不會(huì)溢出,因?yàn)樗鼈円驯粩U(kuò)展。 char * char即使允許,也不是有意義的操作。 但是int * int確實(shí)會(huì)溢出,即使我們有一個(gè)長類型也可以存儲(chǔ)此值而不會(huì)溢出。 byte和short都隱式加寬,但不是int 。 應(yīng)該真正地將long擴(kuò)展,但是我們沒有一個(gè)更寬泛的基本類型,這曾經(jīng)是有意義的,但是如今64位基本類型看起來并不那么長。
師
在除數(shù)可以擴(kuò)大結(jié)果的意義上,除法有些奇怪。 除數(shù)比分子寬并不意味著結(jié)果會(huì)更大(但通常會(huì)更小)
System.out.println(is(Byte.MAX_VALUE / (byte) 1)); System.out.println(is(Byte.MAX_VALUE / (short) 1)); System.out.println(is(Byte.MAX_VALUE / (char) 1)); System.out.println(is(Byte.MAX_VALUE / (int) 1)); System.out.println(is(Byte.MAX_VALUE/ (long) 1));版畫
int: 127 int: 127 int: 127 int: 127 long: 127當(dāng)你把一個(gè)byte/byte你會(huì)得到一個(gè)int即使你不能得到比一個(gè)大的值byte 。 (除非您將Byte.MIN_VALUE除以-1(在這種情況下, short會(huì)這樣做),并且如果您將byte/long除以byte/long即使值仍然不能大于byte您也會(huì)得到long 。
模量
當(dāng)執(zhí)行模數(shù)a % b ,結(jié)果不能大于b 。 但是模數(shù)會(huì)擴(kuò)大結(jié)果而不是減少結(jié)果。
System.out.println(is(Byte.MAX_VALUE % Byte.MAX_VALUE)); System.out.println(is(Byte.MAX_VALUE % Short.MAX_VALUE)); System.out.println(is(Byte.MAX_VALUE % Character.MAX_VALUE)); System.out.println(is(Byte.MAX_VALUE % Integer.MAX_VALUE)); System.out.println(is(Byte.MAX_VALUE % Long.MAX_VALUE));System.out.println(is(Byte.MAX_VALUE % (byte) 2)); System.out.println(is(Short.MAX_VALUE % (byte) 2)); System.out.println(is(Character.MAX_VALUE % (byte) 2)); System.out.println(is(Integer.MAX_VALUE % (byte) 2)); System.out.println(is(Long.MAX_VALUE % (byte) 2));版畫
int: 0 int: 127 int: 127 int: 127 long: 127 int: 1 int: 1 int: 1 int: 1 long: 1如果將X乘以一個(gè)數(shù),結(jié)果將不會(huì)比X寬/大,只能變小。 但是,捷豹路虎say必須擴(kuò)大范圍。 如果將X乘以一個(gè)byte ,則結(jié)果只能在一個(gè)byte的范圍內(nèi)。
我還提到了一元運(yùn)算,也許最簡單的是一元減號。
System.out.println(is(-Byte.MIN_VALUE)); System.out.println(is(-Short.MIN_VALUE)); System.out.println(is(-Character.MIN_VALUE)); System.out.println(is(-Integer.MIN_VALUE)); System.out.println(is(-Long.MIN_VALUE));版畫
int: 128 int: 32768 int: 0 int: -2147483648 long: -9223372036854775808在前三種情況下,類型擴(kuò)大了。 一個(gè)byte可以擴(kuò)大到short ,但是作為一個(gè)int是正確的。 但是對于int和long ,它并沒有擴(kuò)大,您可能會(huì)遇到罕見的溢出。
一元奇數(shù)是一元加號,它不會(huì)更改值(因此無法更改其范圍),但可以擴(kuò)大值。
System.out.println(is(+Byte.MIN_VALUE)); System.out.println(is(+Short.MIN_VALUE)); System.out.println(is(+Character.MIN_VALUE)); System.out.println(is(+Integer.MIN_VALUE)); System.out.println(is(+Long.MIN_VALUE));版畫
int: -128 int: -32768 int: 0 int: -2147483648 long: -9223372036854775808我們可以解決這個(gè)問題嗎?
不幸的是沒有。 有太多代碼依賴于此邏輯。 例如說你寫這樣的東西。
long i = ... byte b = ... long l = i % b + Integer.MAX_VALUE;如果i%b要從long變?yōu)閎yte ,則此表達(dá)式可能會(huì)溢出。
結(jié)論
Java可以在需要時(shí)擴(kuò)展某些值,但也不能擴(kuò)展某些int操作,這實(shí)際上應(yīng)該很long 。 即使這可能更合邏輯,也永遠(yuǎn)不會(huì)給出更窄的結(jié)果。
我們需要做的是了解邊緣情況,尤其是int * int ,并在看到這樣的操作時(shí)知道自己擴(kuò)大它們。 例如
long l = (long) a * b;除非我們確信a * b將適合int值。
翻譯自: https://www.javacodegeeks.com/2015/02/inconsistent-operation-widen-rules-java.html
總結(jié)
以上是生活随笔為你收集整理的Java中不一致的操作会扩大规则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pc上发现一款口袋妖怪硬盘版的中文游戏,
- 下一篇: 电脑cpu水冷怎么更换(如何更换水冷)