Java中求Logn/log2 的精度問題
java求Logn/log2精度
經(jīng)過本人測試,java 中 , 一直到 2的492 次方(這么大的數(shù),平時(shí)夠用了) ;用 Math.log(n) / Math.log(x) 公式都會(huì)產(chǎn)生一個(gè)整數(shù)
例如
int x = 2 ; double n = Math.pow(2, 234) System.out.println(Math.log(n) / Math.log(x));
輸出的是 234.0
而到了 2的493次方,結(jié)果是493.00000000000006 ; 所以,平時(shí)用這個(gè)公式來確定n是否是2的整數(shù)次冪足夠了!
程序如下:
public class Test { public static void main(String[] args) { // System.out.println(Math.pow(2, 23)); int x = 2 ; double n = Math.pow(2, 493) ; System.out.println(Math.log(n) / Math.log(x)); } }
java 處理高精度計(jì)算
Double.valueOf(String) and Float.valueOf(String)都會(huì)丟失精度。
為了解決這個(gè)問題,需要用到BigDecimal類。
使用的BigDecimal類的時(shí)候需要注意的地方:
1. 在實(shí)例化BigDecimal 的時(shí)候用 new BigDecimal(String) 代替new BigDecimal(double) ,new BigDecimal(float)在《Effective Java》書中有提到
2. 比較兩個(gè)數(shù)的時(shí)候用compareTo 小于返回-1 , 等于返回0 , 大于返回1
import java.math.BigDecimal; public class ArithmeticUtil { /* * 小數(shù)精確的位數(shù) */ private static final int DEF_DIV_SCALE = 10; /** * 提供精確的加法運(yùn)算。 * * @param v1 * 被加數(shù) * @param v2 * 加數(shù) * @return 兩個(gè)參數(shù)的和 */ public static double add(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } /** * 提供精確的加法運(yùn)算。 * * @param v1 * 被加數(shù) * @param v2 * 加數(shù) * @return 兩個(gè)參數(shù)的和 */ public static BigDecimal add(String v1, String v2) { BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.add(b2); } /** * 提供精確的加法運(yùn)算。 String * * @param v1 * 被加數(shù) * @param v2 * 加數(shù) * @return 兩個(gè)參數(shù)的和 */ public static String strAdd(String v1, String v2,int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } /** * 提供精確的減法運(yùn)算。 * * @param v1 * 被減數(shù) * @param v2 * 減數(shù) * @return 兩個(gè)參數(shù)的差 */ public static double sub(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /** * 提供精確的減法運(yùn)算。 * * @param v1 * 被減數(shù) * @param v2 * 減數(shù) * @return 兩個(gè)參數(shù)的差 */ public static BigDecimal sub(String v1, String v2) { BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.subtract(b2); } /** * 對(duì)一個(gè)數(shù)字取精度 * @param v * @param scale * @return */ public static BigDecimal round(String v, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(v); BigDecimal one = new BigDecimal("1"); return b.divide(one, scale, BigDecimal.ROUND_HALF_UP); } /** * 提供精確的減法運(yùn)算。String * * @param v1 * 被減數(shù) * @param v2 * 減數(shù) * @return 兩個(gè)參數(shù)的差 */ public static String strSub(String v1, String v2,int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } /** * 提供精確的乘法運(yùn)算。 * * @param v1 * 被乘數(shù) * @param v2 * 乘數(shù) * @return 兩個(gè)參數(shù)的積 */ public static double mul(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * 提供精確的乘法運(yùn)算。 * * @param v1 * 被乘數(shù) * @param v2 * 乘數(shù) * @return 兩個(gè)參數(shù)的積 */ public static BigDecimal mul(String v1, String v2) { BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.multiply(b2); } /** * 提供精確的乘法運(yùn)算。 保留scale 位小數(shù) * * @param v1 * 被乘數(shù) * @param v2 * 乘數(shù) * @return 兩個(gè)參數(shù)的積 */ public static double mul2(double v1, double v2,int scale) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return round(b1.multiply(b2).doubleValue(),scale); } /** * 提供精確的乘法運(yùn)算。 保留scale 位小數(shù) String * * @param v1 * 被乘數(shù) * @param v2 * 乘數(shù) * @return 兩個(gè)參數(shù)的積 */ public static String strMul2(String v1, String v2,int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } /** * 提供(相對(duì))精確的除法運(yùn)算,當(dāng)發(fā)生除不盡的情況時(shí),精確到 小數(shù)點(diǎn)以后10位,以后的數(shù)字四舍五入。 * * @param v1 * 被除數(shù) * @param v2 * 除數(shù) * @return 兩個(gè)參數(shù)的商 */ public static BigDecimal div(String v1, String v2) { return div(v1, v2, DEF_DIV_SCALE); } /** * 提供(相對(duì))精確的除法運(yùn)算,當(dāng)發(fā)生除不盡的情況時(shí),精確到 小數(shù)點(diǎn)以后10位,以后的數(shù)字四舍五入。 * * @param v1 * 被除數(shù) * @param v2 * 除數(shù) * @return 兩個(gè)參數(shù)的商 */ public static double div(double v1, double v2) { return div(v1, v2, DEF_DIV_SCALE); } /** * 提供(相對(duì))精確的除法運(yùn)算。當(dāng)發(fā)生除不盡的情況時(shí),由scale參數(shù)指 定精度,以后的數(shù)字四舍五入。 * * @param v1 * 被除數(shù) * @param v2 * 除數(shù) * @param scale * 表示需要精確到小數(shù)點(diǎn)以后幾位。 * @return 兩個(gè)參數(shù)的商 */ public static double div(double v1, double v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供(相對(duì))精確的除法運(yùn)算。當(dāng)發(fā)生除不盡的情況時(shí),由scale參數(shù)指 定精度,以后的數(shù)字四舍五入。 * * @param v1 * 被除數(shù) * @param v2 * 除數(shù) * @param scale * 表示需要精確到小數(shù)點(diǎn)以后幾位。 * @return 兩個(gè)參數(shù)的商 */ public static BigDecimal div(String v1, String v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP); } /** * 精確的除法運(yùn)算。除不盡時(shí),由scale參數(shù)指 定精度 四舍五入。string * * @param v1 * 被除數(shù) * @param v2 * 除數(shù) * @param scale * 表示需要精確到小數(shù)點(diǎn)以后幾位。 * @return 兩個(gè)參數(shù)的商 */ public static String strDiv(String v1, String v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString(); } /** * 精確的除法運(yùn)算。除不盡時(shí),由scale參數(shù)指 定精度 四舍五入。string * * @param v1 * 被除數(shù) * @param v2 * 除數(shù) * @param scale * 表示需要精確到小數(shù)點(diǎn)以后幾位。 * @return 兩個(gè)參數(shù)的商 */ public static BigDecimal bigDiv(String v1, String v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP); } /** * 取余數(shù) string * @param v1 * @param v2 * @param scale * @return */ public static BigDecimal strRemainder(String v1,String v2, int scale){ if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP); } /** * 取余數(shù) string * @param v1 * @param v2 * @param scale * @return string */ public static String strRemainder2Str(String v1,String v2, int scale){ if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } /** * 比較大小 如果v1 大于v2 則 返回true 否則false * @param v1 * @param v2 * @return */ public static boolean strcompareTo(String v1,String v2){ BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); int bj = b1.compareTo(b2); boolean res ; if(bj>0) res = true; else res = false; return res; } /** * 比較大小 如果v1 大于等于v2 則 返回true 否則false * @param v1 * @param v2 * @return */ public static boolean strcompareTo2(String v1,String v2){ BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); int bj = b1.compareTo(b2); boolean res ; if(bj>=0) res = true; else res = false; return res; } /** * 比較大小 如果v1 等于v2 則 返回true 否則false * @param v1 * @param v2 * @return */ public static boolean strcompareTo3(String v1,String v2){ BigDecimal b1 = new BigDecimal(v1); BigDecimal b2 = new BigDecimal(v2); int bj = b1.compareTo(b2); boolean res ; if(bj==0) res = true; else res = false; return res; } /** * 取余數(shù) BigDecimal * @param v1 * @param v2 * @param scale * @return */ public static BigDecimal bigRemainder(BigDecimal v1,BigDecimal v2, int scale){ if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP); } /** * 提供精確的小數(shù)位四舍五入處理。 * * @param v * 需要四舍五入的數(shù)字 * @param scale * 小數(shù)點(diǎn)后保留幾位 * @return 四舍五入后的結(jié)果 */ public static double round(double v, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精確的小數(shù)位四舍五入處理。string * * @param v * 需要四舍五入的數(shù)字 * @param scale * 小數(shù)點(diǎn)后保留幾位 * @return 四舍五入后的結(jié)果 */ public static String strRound(String v, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(v); return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
ElasticSearch6.2.3+head插件安裝的方法步驟
這篇文章主要介紹了ElasticSearch6.2.3+head插件安裝的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02IDEA2020.1使用LeetCode插件運(yùn)行并調(diào)試本地樣例的方法詳解
這篇文章主要介紹了IDEA2020.1使用LeetCode插件運(yùn)行并調(diào)試本地樣例的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-09-09使用BeanFactory實(shí)現(xiàn)創(chuàng)建對(duì)象
這篇文章主要為大家詳細(xì)介紹了使用BeanFactory實(shí)現(xiàn)創(chuàng)建對(duì)象,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08VSCode中開發(fā)JavaWeb項(xiàng)目的詳細(xì)過程(Maven+Tomcat+熱部署)
這篇文章主要介紹了VSCode中開發(fā)JavaWeb項(xiàng)目(Maven+Tomcat+熱部署),本文分步驟通過圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09Java使用JSONObject需要的6個(gè)jar包下載地址
這篇文章主要介紹了Java使用JSONObject需要的6個(gè)jar包下載地址,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Java?使用geotools讀取tiff數(shù)據(jù)的示例代碼
這篇文章主要介紹了Java?通過geotools讀取tiff,一般對(duì)于tiff數(shù)據(jù)的讀取,都會(huì)借助于gdal,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04Java實(shí)現(xiàn)上傳和下載功能(支持多個(gè)文件同時(shí)上傳)
這篇文章主要介紹了Java實(shí)現(xiàn)上傳和下載功能,支持多個(gè)文件同時(shí)上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12