package zj.hy.love; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; /** * 在‘e’的数列中所能找到的第一个十位数质数 * @author ZJ * @since 2017-1-3 */ public class Ques20170103_02 { private static final BigInteger two = new BigInteger("2"); private static final BigInteger one = new BigInteger("1"); private static final BigInteger zero = new BigInteger("0"); private static final BigInteger oppositeOne = new BigInteger("-1"); /** * 自然数e = 1/0!+1/1!+1/2!+....+1/(n-1)!+1/n! n=defaultCircle * 当defaultCircle值越大模拟的自然数e越接近真实值 */ private static final int defaultCircle = 1000000; /** * 存放一百以内的全部质数 */ private static final List<BigInteger> primeList = new ArrayList<BigInteger>(); static{ // 一百以内的全部素数 int[] prime = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97}; for (int i = 0; i < prime.length; i++) { primeList.add(new BigInteger(prime[i]+"")); } } /** * 在任意数字型序列中寻找第一个bit位的质数<br> * 数字型序列如:46165/1234.8974 * @param array 数字数列 * @param bit 截取字符串的长度 * @return 不存在时返回-1,存在则返回改质数 */ public BigInteger findTenPrimeOfArray(String array,int bit){ if(array.contains(".")){ String[] a = array.split("\\."); if(a[0].length()>=bit){ return getFirstTenPrime(a[0],bit); } if(a[1].length()>=bit){ return getFirstTenPrime(a[1],bit); } }else{ if(array.length()>=bit){ return getFirstTenPrime(array,bit); } } return oppositeOne; } /** * 从左到右依次截取字符串的bit位转换为数字,<br> * 判断这个数字是否为质数,若是则返回改数字,若不存在返回-1 * @param array 数字型字符串 * @return */ private BigInteger getFirstTenPrime(String array,int bit){ int len = array.length(); int i = 0; BigInteger temp; boolean flag; while(i<len-1-bit){ temp = new BigInteger(array.substring(0+i, bit+i)); flag = judgeNumberIsPrime(temp); if(flag){ return temp; } i++; } return oppositeOne; } /** * 测试一个数是否为质数<br> * @param num * @return */ public boolean judgeNumberIsPrime(BigInteger num){ if(num.compareTo(two)==-1){ return false; } int size = primeList.size(); for (int i = 0; i < size; i++) { BigInteger res = montgomery(primeList.get(i),num.subtract(one),num); if(!res.equals(one)&&!res.equals(zero)){ return false; } } return true; } /** * 蒙哥马利算法 * @param a 底数 * @param b 指数 * @param m 模数 * @return */ public BigInteger montgomery(BigInteger n,BigInteger p,BigInteger m){ BigInteger r = n.mod(m); BigInteger tmp = one; while(p.compareTo(one)==1){ if(!p.mod(two).equals(zero)){ tmp = tmp.multiply(r).mod(m); } r = r.multiply(r).mod(m); p = p.divide(two); } return r.multiply(tmp).mod(m); } /** * 获取自然数e * @param scale 精度 * @return */ public static BigDecimal getNaturalConstant(int scale){ BigDecimal e = new BigDecimal(0); BigDecimal t = new BigDecimal(1); for (int i = 1; i < defaultCircle; i++) { t = t.divide(new BigDecimal(i), scale, BigDecimal.ROUND_HALF_UP); e = e.add(t); } return e; } //测试在‘e’的数列中所能找到的第一个十位数质数 public static void main(String[] args) { Ques20170103_02 ques = new Ques20170103_02(); final int step = 1000; for (int i = 1; i < 1000; i++) { String e = getNaturalConstant(step*i).toString();//获取自然数小数点后1000位 String res = ques.findTenPrimeOfArray(e, 10).toString(); if(!oppositeOne.equals(res)){ System.out.println(res); break; } } } }
寻找数字型序列的第一个任意位长的质数,以及精确获取自然数的特定位长,方法支持亿级运算
猜你喜欢
转载自307279262.iteye.com/blog/2348798
今日推荐
周排行