`
爱园园真是太好了
  • 浏览: 584 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

寻找数字型序列的第一个任意位长的质数,以及精确获取自然数的特定位长,方法支持亿级运算

    博客分类:
  • java
阅读更多
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;
			}
		}			
	}
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics