日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

java安全編碼指南之:Number操作詳解

瀏覽:49日期:2022-08-24 18:03:19

簡介

java中可以被稱為Number的有byte,short,int,long,float,double和char,我們在使用這些Nubmer的過程中,需要注意些什么內容呢?一起來看看吧。

Number的范圍

每種Number類型都有它的范圍,我們看下java中Number類型的范圍:

java安全編碼指南之:Number操作詳解

考慮到我們最常用的int操作,雖然int的范圍夠大,但是如果我們在做一些int操作的時候還是可能超出int的范圍。

超出了int范圍會發送什么事情呢?看下面的例子:

public void testIntegerOverflow(){ System.out.println(Integer.MAX_VALUE+1000); }

運行結果:-2147482649。

很明顯Integer.MAX_VALUE+1000將會超出Integer的最大值范圍,但是我們沒有得到異常提醒,反而得到了一個錯誤的結果。

正確的操作是如果我們遇到了Overflow的問題,需要拋出異常:ArithmeticException。

怎么防止這種IntegerOverflow的問題呢?一般來講,我們有下面幾種方式。

第一種方式:在做Integer操作之前,進行預判斷是否超出范圍:

舉個例子:

static final int safeAdd(int left, int right) { if (right > 0 ? left > Integer.MAX_VALUE - right : left < Integer.MIN_VALUE - right) { throw new ArithmeticException('Integer overflow'); } return left + right; }

上面的例子中,我們需要進行兩個整數相加操作,在相加之前,我們需要進行范圍的判斷,從而保證計算的安全性。

第二種方式:使用Math的addExact和multiplyExact方法:

Math的addExact和multiplyExact方法已經提供了Overflow的判斷,我們看下addExact的實現:

public static int addExact(int x, int y) { int r = x + y; // HD 2-12 Overflow iff both arguments have the opposite sign of the result if (((x ^ r) & (y ^ r)) < 0) { throw new ArithmeticException('integer overflow'); } return r; }

看下怎么使用:

public int addUseMath(int a, int b){ return Math.addExact(a,b); }

第三種方式:向上轉型

既然超出了Integer的范圍,那么我們可以用范圍更大的long來存儲數據。

public static long intRangeCheck(long value) { if ((value < Integer.MIN_VALUE) || (value > Integer.MAX_VALUE)) { throw new ArithmeticException('Integer overflow'); } return value; } public int addUseUpcasting(int a, int b){ return (int)intRangeCheck((long)a+(long)b); }

上面的例子中,我們將a+b轉換成了兩個long相加,從而保證不溢出范圍。

然后進行一次范圍比較,從而判斷相加之后的結果是否仍然在整數范圍內。

第四種方式:使用BigInteger

我們可以使用BigInteger.valueOf(a)將int轉換成為BigInteger,再進行后續操作:

public int useBigInteger(int a, int b){ return BigInteger.valueOf(a).add(BigInteger.valueOf(b)).intValue(); }

區分位運算和算數運算

我們通常會對Integer進行位運算或者算數運算。雖然可以進行兩種運算,但是最好不要將兩種運算同時進行,這樣會造成混淆。

比如下面的例子:

x += (x << 1) + 1;

上面的例子是想做什么呢?其實它是想將3x+1的值賦給x。

但是這樣寫出來讓人很難理解,所以我們需要避免這樣實現。

再看下面的一個例子:

public void testBitwiseOperation(){ int i = -10; System.out.println(i>>>2); System.out.println(i>>2); System.out.println(i/4); }

本來我們想做的是將i除以4,結果發現只有最后一個才是我們要的結果。

我們來解釋一下,第一個i>>>2是邏輯右移,將會把最左邊的填充成0,所以得出的結果是一個正值1073741821。

第二個i>>2是算數右移,最左邊的還是會填充成1,但是會向下取整,所以得出結果是-3.

直接使用i/4,我們是向上取整,所以得出結果是-2.

注意不要使用0作為除數

我們在使用變量作為除數的時候,一定要注意先判斷是否為0.

兼容C++的無符號整數類型

在java中只有16位的char表示的是無符號整數,而int實際上表示的是帶符號的整數。

而在C或者C++中是可以直接表示無符號的整數的,那么,如果我們有一個32位的無符號整數,該怎么用java來處理呢?

public int readIntWrong(DataInputStream is) throws IOException { return is.readInt(); }

看上面的例子,我們從Stream中讀取一個int值,如果是一個32位的無符號整數,那么讀出來int就變成了有符號的負整數,這和我們的期望是相符的。

考慮一下,long是64位的,我們是不是可以使用long來表示32位的無符號整數呢?

public long readIntRight(DataInputStream is) throws IOException{ return is.readInt() & 0xFFFFFFFFL; // Mask with 32 one-bits }

看上面的例子,我們返回的是long,如果將32位的int轉換成為64位的long,會自動根據符號位進行補全。

所以這時候我們需要和0xFFFFFFFFL進行mask操作,將高32位重置為0.

NAN和INFINITY

在整型運算中,除數是不能為0的,否則直接運行異常。但是在浮點數運算中,引入了NAN和INFINITY的概念,我們來看一下Double和Float中的定義。

public static final double POSITIVE_INFINITY = 1.0 / 0.0;public static final double NEGATIVE_INFINITY = -1.0 / 0.0;public static final double NaN = 0.0d / 0.0;

public static final float POSITIVE_INFINITY = 1.0f / 0.0f;public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;public static final float NaN = 0.0f / 0.0f;

1除以0就是INFINITY,而0除以0就是NaN。

接下來,我們看一下NAN和INFINITY的比較:

public void compareInfinity(){ System.out.println(Double.POSITIVE_INFINITY == Double.POSITIVE_INFINITY); }

運行結果是true。

public void compareNaN(){ System.out.println(Double.NaN == Double.NaN); }

運行結果是false。

可以看到NaN和NaN相比是false。

那么我們怎么比較NaN呢?

別急,Double提供了一個isNaN方法,我們可以這樣使用:

System.out.println(Double.isNaN(Double.NaN));

接下來我們看一個在代碼中經常會用到的一個Double解析:

public void incorrectParse(String userInput){ double val = 0; try { val = Double.valueOf(userInput); } catch (NumberFormatException e) { } //do something for val }

這段代碼有沒有問題?咋看下好像沒有問題,但是,如果我們的userInput是NaN,Infinity,或者-Infinity,Double.valueOf是可以解析得到結果的。

public void testNaN(){ System.out.println(Double.valueOf('NaN')); System.out.println(Double.valueOf('Infinity')); System.out.println(Double.valueOf('-Infinity')); }

運行輸出:

NaN

Infinity

-Infinity

所以,我們還需要額外去判斷NaN和Infinity:

public void correctParse(String userInput){ double val = 0; try { val = Double.valueOf(userInput); } catch (NumberFormatException e) { } if (Double.isInfinite(val)){ // Handle infinity error } if (Double.isNaN(val)) { // Handle NaN error } //do something for val }

不要使用float或者double作為循環的計數器

考慮下面的代碼:

for (float x = 0.1f; x <= 1.0f; x += 0.1f) { System.out.println(x);}

上面的代碼有什么問題呢?

我們都知道java中浮點數是不準確的,但是不一定有人知道為什么不準確。

這里給大家解釋一下,計算機中所有與的數都是以二進制存儲的,我們以0.6為例。

0.6轉成為二進制格式是乘2取整,0.6x2=1.2,取整剩余0.2,繼續上面的步驟0.2x2=0.4,0.4x2=0.8,0.8x2=1.6,取整剩余0.6,產生了一個循環。

所以0.6的二進制格式是.1001 1001 1001 1001 1001 1001 1001 … 無限循環下去。

所以,有些小數是無法用二進制精確的表示的,最終導致使用float或者double作為計數器是不準的。

BigDecimal的構建

為了解決float或者Double計算中精度缺失的問題,我們通常會使用BigDecimal。

那么在使用BigDecimal的時候,請注意一定不要從float構建BigDecimal,否則可能出現意想不到的問題。

public void getFromFloat(){ System.out.println(new BigDecimal(0.1)); }

上面的代碼,我們得到的結果是:0.1000000000000000055511151231257827021181583404541015625。

這是因為二進制無法完美的展示所有的小數。

所以,我們需要從String來構建BigDecimal:

public void getFromString(){ System.out.println(new BigDecimal('0.1')); }

類型轉換問題

在java中各種類型的Number可以互相進行轉換:

比如:

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

或者反向:

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

從大范圍的類型轉向小范圍的類型時,我們要考慮是否超出轉換類型范圍的情況:

public void intToByte(int i){ if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE)) { throw new ArithmeticException('Value is out of range'); } byte b = (byte) i; }

比如上面的例子中,我們將int轉換成為byte,那么在轉換之前,需要先判斷int是否超出了byte的范圍。

同時我們還需要考慮到精度的切換,看下面的例子:

public void intToFloat(){ System.out.println(subtraction(1111111111,1111111111)); } public int subtraction(int i , float j){ return i - (int)j; }

結果是多少呢?

答案不是0,而是-57。

為什么呢?

因為這里我們做了兩次轉換,第一次從1111111111轉換到float,float雖然有32位,但是只有23位是存放真正的數值的,1位是符號位,剩下的8位是指數位。

所以從1111111111轉換到float發送了精度丟失。

我們可以把subtraction方法修改一下,首先判斷float的范圍,如果超出了23bit的表示范圍,則說明發送了精度丟失,我們需要拋出異常:

public int subtraction(int i , float j){ System.out.println(j); if ((j > 0x007fffff) || (j < -0x800000)) { throw new ArithmeticException('Insufficient precision'); } return i - (int)j; }

當然還有一種辦法,我們可以用精度更高的double來做轉換,double有52位來存放真正的數據,所以足夠了。

public int subtractionWithDouble(int i , double j){ System.out.println(j); return i - (int)j; }

本文的代碼:

learn-java-base-9-to-20/tree/master/security

以上這篇java安全編碼指南之:Number操作詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩三级视频| 久久精品国产亚洲夜色av网站| 亚洲午夜电影| 久久中文字幕av| 国产精品7m凸凹视频分类| 国产综合婷婷| 老鸭窝毛片一区二区三区| 国产精品7m凸凹视频分类| 日韩一级网站| 婷婷亚洲精品| 国产精品mv在线观看| 精品美女在线视频| 日韩电影在线视频| 激情欧美一区| 中文字幕一区二区三区日韩精品 | 精品亚洲成人| av中文字幕在线观看第一页| 成人av三级| 免费看欧美美女黄的网站| 日韩免费精品| 麻豆久久久久久| 亚洲免费福利| 国产精品日本| 国产日韩亚洲欧美精品| 国产一区二区三区国产精品| 久久精品导航| 一二三区精品| 久久av导航| 久久久777| 亚洲欧洲国产精品一区| 奇米狠狠一区二区三区| 麻豆国产精品777777在线| 成人国产精品一区二区网站| 欧美13videosex性极品| 2023国产精品久久久精品双| 亚洲精品高潮| 精品成人18| 国产美女精品| 久久影院资源站| 午夜久久影院| 国产精品极品| 婷婷激情综合| 国产伦精品一区二区三区视频| 日本综合字幕| 日本不卡一区二区| 日本一区二区免费高清| 视频一区视频二区在线观看| 国产精品一二| 91九色精品| 国产精品蜜月aⅴ在线| 欧美日韩水蜜桃| 欧美在线精品一区| 久久久久午夜电影| 国产视频网站一区二区三区| 久久久久国产精品一区二区| 日本不卡在线视频| 久久久影院免费| 国产精品多人| 爽好久久久欧美精品| 成人国产精品久久| 美女日韩在线中文字幕| 日本一区二区高清不卡| 日韩在线观看中文字幕| 黄色aa久久| 欧美亚洲二区| 亚洲深夜av| 日本一二区不卡| 日韩高清在线一区| 99久久精品费精品国产| 久久99精品久久久久久园产越南| 亚洲欧洲日本mm| 福利一区二区| 欧美啪啪一区| 久久亚洲不卡| 婷婷国产精品| 免费观看亚洲天堂| 亚洲精品综合| 午夜日韩av| 久久91导航| 韩国一区二区三区视频| 日韩国产高清在线| 午夜一级在线看亚洲| 色婷婷狠狠五月综合天色拍| 久久wwww| 久久国产三级| 亚洲精品成人一区| 尤物精品在线| 久久青草久久| 中文字幕在线免费观看视频| 欧美亚洲一区二区三区| 91成人超碰| 日韩欧美二区| 国产成人77亚洲精品www| 国产欧美日韩精品高清二区综合区| 日韩影院在线观看| 亚洲精品极品少妇16p| 91精品国产成人观看| 精品国产一区二| 国产欧美日韩精品高清二区综合区 | 欧美成人aaa| 婷婷成人av| 香蕉成人久久| 亚洲黄页一区| 欧美~级网站不卡| 久久人人97超碰国产公开结果| 久久久久久婷| 国产66精品| 成人在线观看免费视频| 老司机精品视频网| 国产精品hd| 久久av导航| 欧美1区2区3| 国产精品magnet| 欧美黑人巨大videos精品| 日韩国产欧美三级| 亚洲3区在线| 综合一区av| 亚洲三级在线| 日韩三级精品| 欧美精品国产| 久久国产婷婷国产香蕉| 欧美日韩一区自拍| 国产欧美日韩精品一区二区免费| 欧美精品中文| 国产精品久久久久久久久久白浆| 久久爱www.| 97精品国产一区二区三区| 色综合狠狠操| 久久久精品五月天| 99国产精品视频免费观看一公开| 在线一区视频| 在线成人直播| 热久久久久久久| 亚洲免费资源| 青青草国产成人99久久| 国产精品伦一区二区| 美女免费视频一区| 捆绑调教日本一区二区三区| 日本久久成人网| 欧美国产91| 亚洲一区中文| 日本视频在线一区| 国产欧美另类| 成人亚洲欧美| 尹人成人综合网| 日韩精品欧美大片| 国产免费av国片精品草莓男男| 国产精品99久久免费| 黄毛片在线观看| 亚洲国产成人精品女人| 亚洲精品韩国| 精品一区二区三区亚洲| 亚洲成a人片| 模特精品在线| 欧美午夜三级| 日本一二区不卡| 欧美日韩高清| 日韩精品亚洲专区在线观看| 精品理论电影在线| 国产真实久久| 日韩欧美中文在线观看| 国产欧美日韩一区二区三区在线| 91综合视频| 99热精品在线观看| 欧美日韩亚洲一区三区| 97精品国产福利一区二区三区| 蜜桃tv一区二区三区| 日韩久久99| 日韩免费看片| 在线看片日韩| 精品国产亚洲一区二区三区在线 | 欧美激情福利| 久久久久国产精品一区二区| 中文一区一区三区免费在线观 | 女主播福利一区| 久久国产精品免费精品3p| 日本在线啊啊| 三级久久三级久久久| 中文av在线全新| 日韩欧美另类中文字幕| 日韩伦理一区| 日本欧美久久久久免费播放网| 国产成人免费| 在线国产日韩| 国产一区2区在线观看| 午夜在线视频观看日韩17c| 美女精品一区二区| 亚洲一区二区免费在线观看| 日韩av免费大片| 日本不卡视频一二三区| 久久久久亚洲| 毛片不卡一区二区| 亚洲综合色婷婷在线观看| 亚洲一级少妇| 国产精品久久久久久久久久白浆| 亚洲精品a级片| 精品久久精品| 日本亚洲视频在线| 女主播福利一区| 精品国产中文字幕第一页|