Using biginteger to find the sequence of sum of powers - java

Sum(N) =1^1+2^2+3^3+...+N^N
Using Java,
How would I use BigInteger to find the smallest integer N such that the value of Sum(N) is larger than 10^20?
I'm really stuck,please give me some advice
This is what I have so far:
import java.math.BigInteger;
public class PROJECTV1 {
public static void main(String [] args) {
BigInteger bResult= bigFunctionExample_2();
System.out.println(" => result_got:"+ bResult);
System.out.println(); //newline
}// end_main
public static BigInteger bigFunctionExample_2() {
BigInteger bSum = BigInteger.ZERO;
BigInteger bTmp;
String sSum;
// BigInteger bResult =0;
for (int i=1; ; i++) {
bTmp = BigInteger.valueOf(i);
bTmp = bTmp.pow(i); // i^i
bSum = bSum.add(bTmp); // sum = i^i+ (i-1)^(i-1)+ ....
sSum = bSum.toString();
if ( sSum.length() >21) {
System.out.println("i="+i +" bSum ="+bSum);
break;
}//
}//end_for
return bSum; // result
} // end_bigFunctionExample_2
}

Looking at your code, you have a line bTmp.pow(2). That squares the numbers in your series, but you need to raise bTmp to the bTmp power. Java doesn’t seem to want to take a BigInteger as an argument to pow, but you could replace pow with another for loop.
Also, sSum.length() >30 looks like it will only occur if your sum is greater than or equal to 1029. Is there a reason you convert the number to a string each time through the loop, rather than comparing the number to 1020? Perhaps you could put something like bSum > bMax as the test condition in your for loop, rather than leaving it blank and exiting with a break. Then you could make a new BigInteger bMax and set it to 1020 at the start of your code.
For testing, you could set bMax to something small, like 100, and see if your program gives the correct result. You can calculate the first few steps of the series by hand to check your program.

Here is a clue computing some factorials:
import java.math.*;
public class FactorialBig {
public static BigInteger factorial(BigInteger n) {
if (n.equals(BigInteger.ZERO))
return BigInteger.ONE;
else
return n.multiply(factorial(n.subtract(BigInteger.ONE)));
}
public static void main(String[] args) {
for (int n = 0; n < 20; n++) {
BigInteger f = factorial(new BigInteger(new Integer(n).toString()));
System.out.printf("factorial(%2d) = %20s%n", n, f.toString());
}
}
}
You know you should save the above as a file named "FacotrialBig.java".

Related

Factorial with caching with static int array

static int count = 0;
static long[] cache = new long[3000];
static {
cache[0] = 1;
}
public static void main(String args[]) {
for (int i = 0; i < 100; i++){
factorial_with_cache(2999);
}
System.out.println(count);
}
public static long factorial_with_cache (int n){
if (cache[n] != 0){
return cache[n];
}
cache[n] = n * factorial_with_cache(n - 1);
count++;
return cache[n];
}
I built a function that calculates factorials using a cache (ignoring overflow).
But its runtime isn't any better compares to non-caching function and I found that caching isn't working correctly.
Because I expected a variable 'count' to be 2999 after loop but I fount it is 293465 which is a lot more than that. (without loop, it prints 2999)
What is to wrong with this function?
It is because the range of long datatype:
long 8 bytes (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)
your factorial gives the positive values till you are searching for factorial of 25.
And latter 25 , the value of factorial which are calculated is coming negative (It means you are overflowing long) and your count will work as expected till 65 factorial is calculated (till negative value) and then the value for factorial 66 it reaches to 0..
just try below by printing factorial:
for (int i = 0; i < 100; i++) {
long fact=factorial_with_cache(66);
System.out.println(fact);
}
System.out.println(count);
And the count will be printed as
(forLoopCount*(number-65))+65 , In your case (100*(2999-65))+65 is 293465
becuase the value for factorial it traces back in cache which is not zero is 65th element (at 64 index).
So, let me break it down to you!.
The factorial value of 2999 is 13831198678126180285189556976955373903170397316439366392298225525658528550411773166953335884059334473358394878461205706165250290371348635931517800720356113203873679301399725840687554463393227601721573232498656280819242922032367667908703698446747042372944385912938442812976579204340368770976791467161792908482026536763476497016597962706920837208377639001547222987372530067858391829660217859289638428364594156664891566396944031170356121274762354507422848113071258383496196034678939603033097637499047300169646331468238450491051510529147169986724755958362486789324705690789582425714662973561230539501202732819906031261484507986168459203695503720787715306962036185816958171315101812071237299383615730698142124734425009998777928314671591890471560274735833304904959453223240212984890196653392856493421129589037623689334983609133572374939825462133789731181451373437595533811597516653047843373551034468875167743673579450500731701049557870779579798365517154053116338596649981357437001475641612713380485162624246015285341187194401439315317685276897783748963573748717156161769574677089322363037849660911158458585633121725465474927244487503626338581145799640164089032772344644035725447994450814858680158855133471471566493328118184865933128900946476171137729637721898436949504508364668715924682335777135513931476001478897301228489756952423900549337170685817482869322924594934553551003036605213030431370211238540513634600045019557208087444634144722209572173742863424856277834965975623123264292792298280478857955478985025157988294085407394460004866920398953072534411602822485072110137246001443714741975414563519594304969324628586261528579942898463434127945755294142551435479172585965738348357120600576683876141492098075828585209276254499589065093789637861306274833094913863894376778010733315584027638295254781954610771181735025318637354022424432317128707664886202509105961484149955116054723079614963020498616978124480963271628142440605710424177963844835527047941127068625126602868360296587251294298750977877916818183056200089076530408509618194827562218441437670451251604136520412562026002566902646513949635716489125951469176102624329367970981707309954931234483752478815193819919046940901995441721784302194857041195090070644484327035189466269961364993448728359341757679578928014056475745993488101416681676935545677586672113973814268569600810283522630702882325818379846373279545389063433426048793378977494110923865060198731023168079278694206856962403099309932476468192292446106625814895181431600107247018896474570181676290139870638357579666677214004824737774431290539343185204668200955800140961796618216776009476171707432009598580600540607745366106990480349004177689104965384412262911661517983201465683450782588737131971506423474040743808999564029154506993562074784937792064798377314289371162177187409391071658827235127282051775532062510098826200386957421213481307419200642164870305628383671047981858132767730852384720717147489707456839716365953949812050321036644546531520598864465617319535112877058774715688947419064131580843908826519916664427749093269298823584351338064696733536570891584395455175134404252585951310232510018865069402485833157299381484590749402629481111706181867189617902727630965072766713218125649095472925555254271796579113386470181227145145782044748230689023360927474548519150294185556719080917603439047213543803560461443641342427106320294937680221742056517608545727954154981431896286464615575574564733158523773515339421141910343038451177576269394257673865595696145764470705694837193543322565755533887878425653323007167374034984753189092864395172089482366791478206807334511797067912797698473565007162069130217730303607114778083832632094745399523891591282708699147685012083622118240243657099361565732179240926631053400186908352669170802498149387797404799372830916093992885059492849249732904712828347430127984696856947346045759045222567855013693926840231677378744507230913510338446973920611359605911891548916357205533551076812967546595355169668436624145148563105200443314135704098338484590507017314148504265121657071624074064576429719944333914132659197510167106279294498294744074169106272133146311875939034291810862931519619247593463572388793752634599383049481842295290543310338170244405184924421525345305394766236107745856279305711691002008912764098229027010250648673458812712892369111259770860752452145178192387601343493641928636582411137977634690746620001816089765370131213375846513299799140007308422976207521653093045456515661082438164698099164737736238987887604321282063792704869736900344337373311421647222149710103632831178455467277094227704168859462141968845732336969092143110178250432445572309805015956983080592707178326499816577452815043403343240119997858835910187898983513330297084001603373363523211048122726398082654521129700828750257789083133267241150542349616716479447911942146684493824985807109624549493196517947945459425200477792599605375618154135498044805373036317551108920542553407043626403888641459832178279343412021431660661847004770522200579839513142002891066188195561545147576726674097535863255730732789176509455052905173962566105999668617707172897012592225627884763749139942033144845223843137607945870705185228736818194603451718134984572823575454406177591828833937000873777076143286975370719857688674644025825580933636487558107379601763547689237092321337911968750350350207856080439217177676925119658378188382474722467172490240279700623329997759788303630895974913235271384285181321984740867973019755275212448225468786508612988993837327986628867894584347339330109395315189804183506355434284956511125894328200010602697940710012700738129019153727101417320638801990152011727707236050552882452185513510976137249542985694285597433351175282125687093530484011848796644042625302116542612658623784196206071084087859012798734245795108302784560165996695233840827767813175065781551114331550855078698914278183507913244634124753936290599761240761788764479746965254304384814035524536401827280713121964622571847614159091700055578119247697879649481521588125728024624793157002622383690149851552542093855379183576921256026866677281432077992602744437119929192378994337605857208557227762427170645778895263145703032582860407622708941374105757560394991735954484369165110569420051053146751215121841484529317344915071143082972214834934785117427325907327323956351628058965466260901594022042307157516206082619875478093063424834484331589789332405761721821863933157263022628562426191490028096574592744921026913639837655412782142613217955005774888616730714697231543457088527065900258227520678399439594304530337999272434545057921568904794664270097074820282773506327749449618377008513240527728310551223577424390998477250258491878249375773652218477283959862326057497240566955256032969442610279413479245991485114175229570966285171060322337499286484763536542456863553323594724246140240535192263020188389231521830040129388591953979743641454327796516619093291507799363499952822494950133169703132944736808231037872625326203934365369591454254996804885055848502537888575304997792038113414587636763461378629510437530377514949741965335728283723130064661811549805161260779434177122925330001814574110967154189394698666276840840528442866611330112198472977565560054421966452744887749026774673476597119141918499516457632064030550264890665707146610860517981945041882670296628962352294237074209578011924139474934410391009112814073534671869747359856497734981269800821854176767776274721767346002013762814794961396376464661990588556737167203780040389785178621661600980521079426482525438347561911423287705520933644054859388470137299692798736919535048363842176140811215743626823029475470841708861576378019731723918097050874000743252328975986374873654787685684044366405474086145883963064543443283741094316935375400191188518071061185279429772712931980320767930925743448141144113853867852863500774825091500876956610471375132123918137870632423052883572240769361145098526133695745342449000372928715411061813143685686161256824935345001518961673534243407418799210246313328341659385060893305664721381846776636604396835551452718885897176356302728734712814697152118430414021633905812143491151730458640971651094329383936246692244495665898440957150263861482901326801912557851925957864645963859049318674446902818797438056706130851744872706591971891128651973088423541354578092586738615503678456019321106904965647554452856791768609892202741402821821519518889296407542539996754653930879152617217513639585536181286553740648082906808320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 find it yourself
I know its a lot of scrolling :P
Okay, now during your iterations, factorial of 20 will be 2,432,902,008,176,640,000 and factorial of 21 will be 51,090,942,171,709,440,000 and maximum value for long in java is 9,223,372,036,854,775,807 so, here your cache[19] will be -4,249,290,049,419,214,848 and cache[65] will be 0. which makes all values till cache[2999] to 0. So, every time you call the method factorial_with_cache, it's not serving from cache, but calculating every time (because you're checking if(cache[n] != 0) then return from cache else calculate) causing the count value 293465 instead of 2999.
I've modified the code a little for your understanding.
public class Test2 {
static int count = 0;
static long[] cache = new long[3000];
static {
cache[0] = 1;
}
public static void main(String args[]) {
factorial_with_cache(2999);
}
public static long factorial_with_cache (int n){
if (cache[n] != 0){
return cache[n];
}
cache[n] = n * factorial_with_cache(n - 1);
System.out.println("Factorial(" + n + ") is " + cache[n]);
count++;
return cache[n];
}
}
This will print your calculated fact values.
public class Test2 {
static int count = 0;
static long[] cache = new long[3000];
static {
cache[0] = 1;
}
public static void main(String args[]) {
for (int i = 0; i < 100; i++){
factorial_with_cache(2999);
System.out.println("i[" + i + "] count[" + count +"]");
}
}
public static long factorial_with_cache (int n){
if (cache[n] != 0){
return cache[n];
}
cache[n] = n * factorial_with_cache(n - 1);
count++;
return cache[n];
}
}
This will print count value for each iteration.

Benford's Law Program in Java

I am making a program in Java to see if the Benford's Law is actually true. I am using BigDecimal, but there was an error ever since I implemented it.
import java.lang.*;
import java.math.BigDecimal;
public class BenfordLaw {
public static int oneornot(BigDecimal number) {
String str2num = number.toString();
if(str2num.startsWith("1")) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
int n = 0;
long sum = 0;
for (int i = 0; i < 10000; i++) {
BigDecimal number = BigDecimal.valueOf(Math.pow(2,n));
System.out.println(number);
double newnum = oneornot(number);
sum += newnum;
n+=1;
}
System.out.println(sum);
System.out.println(sum*0.0001);
}
}
If you run this program, there is an error.
The error is in the link below.
https://pastebin.com/ShJmGjdJ
Your program throws exception because of the following line:
BigDecimal number = BigDecimal.valueOf(Math.pow(2,n));
The variable n is incremented by 1 at every iteration up to 9999. Because of that Math.pow(2,n) is becoming so big, that at some point it exceeds the max value of double type. Eventually Double.toString (which is used by BigDecimal.valueOf) returns "Infinity" what leads to NumberFormatException.
Please replace the mentioned line with following to fix your problem:
BigDecimal number = BigDecimal.valueOf(2).pow(n));

Large Optimized IO processing in Java

An input n of the order 10^18 and output should be the sum of all the numbers whose set bits is only 2. For e.g. n = 5 setbit is 101--> 2 set bits. For n = 1234567865432784,How can I optimize the below code?
class TestClass
{
public static void main(String args[])
{
long N,s=0L;
Scanner sc = new Scanner(System.in);
N=sc.nextLong();
for(long j = 1; j<=N; j++)
{
long b = j;
int count = 0;
while(b!=0)
{
b = b & (b-1);
count++;
}
if(count == 2)
{
s+=j;
count = 0;
}
else
{
count = 0;
continue;
}
}
System.out.println(s%1000000007);
s=0L;
}
}
Java has a function
if (Integer.bitCount(i) == 2) { ...
However consider a bit: that are a lot of numbers to inspect.
What about generating all numbers that have just two bits set?
Setting the ith and jth bit of n:
int n = (1 << i) | (1 << j); // i != j
Now consider 31² steps, not yet 1000 with N steps.
As this is homework my advise:
Try to turn the problem around, do the least work, take a step back, find the intelligent approach, search the math core. And enjoy.
Next time, do not spoil yourself of success moments.
As you probably had enough time to think about Joop Eggen's suggestion,
here is how i would do it (which is what Joop described i think):
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
long sum = 0;
for (int firstBitIndex = 0; firstBitIndex < 64; firstBitIndex++) {
long firstBit = 1L << firstBitIndex;
if (firstBit >= n)
break;
for (int secondBitIndex = firstBitIndex + 1; secondBitIndex < 64; secondBitIndex++) {
long value = firstBit | (1L << secondBitIndex);
if (value > n)
break;
sum += value;
}
}
System.out.println(sum % 1000000007);
sc.close();
}
}
Java provides the class BigInteger, which includes a method nextProbablePrime(). This means you could do something like this:
BigInteger n = new BigInteger(stringInputN);
BigInteger test = BigInteger.valueOf(2);
BigInteger total = BigInteger.valueOf(0);
while (test.compareTo(n) < 0){
total = total.add(test);
test = test.nextProbablePrime();
}
System.out.println(total);
This this has an extremely low probability of getting the wrong answer (but nonzero), so you might want to run it twice just to doublecheck. It should be faster than manually iterating it by hand though.

Can't Generate Large Prime Numbers

I'm trying to generate large prime numbers in Java. I use BigIntegers for this. Here is my code to generate and store 10 prime numbers inside an array.
public static void primeGenerator() {
BigInteger[] primeList = new BigInteger[10];
BigInteger startLine = new BigInteger("10");
int startPower = 6;
BigInteger endLine = new BigInteger("10");
int endPower = 9;
int j = 0;
for (BigInteger i = fastExp(startLine,startPower);
i.compareTo(fastExp(endLine,endPower)) <= 0;
i = i.add(BigInteger.ONE)) {
if (checkPrimeFermat(i) == true && j < 10) {
primeList[j] = i;
j++;
}
}
System.out.println(primeList[0]);
System.out.println(primeList[1]);
System.out.println(primeList[2]);
System.out.println(primeList[3]);
System.out.println(primeList[4]);
System.out.println(primeList[5]);
System.out.println(primeList[6]);
System.out.println(primeList[7]);
System.out.println(primeList[8]);
System.out.println(primeList[9]);
}
I wrote my own fastExp function to generate numbers faster. Here are my other functions.
public static BigInteger getRandomFermatBase(BigInteger n)
{
Random rand = new Random();
while (true)
{
BigInteger a = new BigInteger (n.bitLength(), rand);
if (BigInteger.ONE.compareTo(a) <= 0 && a.compareTo(n) < 0)
{
return a;
}
}
}
public static boolean checkPrimeFermat(BigInteger n)
{
if (n.equals(BigInteger.ONE))
return false;
for (int i = 0; i < 10; i++)
{
BigInteger a = getRandomFermatBase(n);
a = a.modPow(n.subtract(BigInteger.ONE), n);
if (!a.equals(BigInteger.ONE))
return false;
}
return true;
}
public static void main(String[] args) throws IOException
{
primeGenerator();
}
public static BigInteger fastExp (BigInteger x, int n){
BigInteger result=x;
int pow2=powof2leN(n);
int residue= n-pow2;
for(int i=1; i<pow2 ; i=i*2){
result=result.multiply(result);
}
for(int i=0 ; i<residue; i++){
result=result.multiply(x);
}
return result;
}
private static int powof2leN(int n) {
for(int i=1; i<=n; i=i*2){
if(i*2>2)
return 1;
}
return 0;
}
}
So the problem is when I try it with small numbers (for example startPower=3, endPower=5) it generates and prints prime numbers. But when I try it with big numbers (for example startPower=5, endPower=7) it doesn't generate anything. How can I improve my code to work with large numbers?
Thank you
First of all, I would like to point out that you did not write this code. You stole it from here and claimed that you wrote it, which is incredibly unethical.
The code is correct. It's just slow. As you increase the power, the code takes increasingly longer. There are two reasons why this occurs:
The Fermat test takes increasingly longer to apply.
BigInteger operations take increasingly longer to execute.
The Fermat test grows like O(k × log2n × log log n × log log log n). BigInteger's addition and subtraction grow like O(n). Obviously, BigInteger is what is slowing you down.
Below is a profile of your code with the power set from 5 to 7.
If you want your code to produce larger and larger primes, you should focus on reducing the number of operations you do on BigIntegers. Here is one such improvement:
Take n.subtract(BigInteger.ONE) outside of your for loop. The result does not need to be calculated many times.
Further suggestions will have to come from the Mathematics folks over on Mathematics Stack Exchange.
Here is a much simpler solution for finding large primes -
BigInteger big = new BigInteger("9001");//or whatever big number you want to start with
BigInteger[] primes = new BigInteger[10];
for(int i=0;i<10;i++){
primes[i]=big=big.nextProbablePrime();
}
It has some limitations outlined here, but based on your code it should be more than enough.
you can use BigInteger(int bitLength, int certainty, Random rnd) constructor
BigInteger b= new BigInteger(20, 1, new Random());
It will generate a prime number for you. bitLength specifies the number of digits you want in your BigInteger, certainity specifies the amount of certainity you want that your BigInteger should be prime.

factorial method doesn't work well!

Hi
this is a factorial method but it prints 0 in the console please help me thanks
public class Demo {
public static void main(String[] args) {
Demo obj = new Demo();
System.out.println(obj.factorial(500));
}
public int factorial(int n) {
int fact = 1;
for (int i = 2; i <= n; i++) {
fact= fact*i;
}
return fact;
}
EDITED:will return Infinity!
public class Demo {
public static void main(String[] args) {
Demo obj = new Demo();
System.out.println(obj.factorial(500));
}
public double factorial(long n) {
double fact = 1;
for (int i = 2; i <= n; i++) {
fact= fact*i;
}
return fact;
}
}
Since 500! equals 1220136825991110068701238785423046926253574342803192842192413588385845373153881997605496447502203281863013616477148203584163378722078177200480785205159329285477907571939330603772960859086270429174547882424912726344305670173270769461062802310452644218878789465754777149863494367781037644274033827365397471386477878495438489595537537990423241061271326984327745715546309977202781014561081188373709531016356324432987029563896628911658974769572087926928871281780070265174507768410719624390394322536422605234945850129918571501248706961568141625359056693423813008856249246891564126775654481886506593847951775360894005745238940335798476363944905313062323749066445048824665075946735862074637925184200459369692981022263971952597190945217823331756934581508552332820762820023402626907898342451712006207714640979456116127629145951237229913340169552363850942885592018727433795173014586357570828355780158735432768888680120399882384702151467605445407663535984174430480128938313896881639487469658817504506926365338175055478128640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 you can't fit it into an int (which ranges up to 2147483647).
Using an int you can only store up to 12!.
Using a long you'll get up to 20!
Using a double you'll get up to 170!.
By convention 0! equals 1;
Here is a solution using BigInteger:
public static BigInteger factorial(int i) {
if (i == 0) {
return BigInteger.ONE;
}
BigInteger n = BigInteger.valueOf(i);
while (--i > 0) {
n = n.multiply(BigInteger.valueOf(i));
}
return n;
}
There's no way you can fit 500! on a 32-bit int.
For calculations involving large numbers, consider using a double or a BigInteger, depending on whether you want an approximate or an exact answer.
(Actually, for 500!, even a double would not be enough: Double.MAX_VALUE is 1.7976931348623157E+308, which will "only" let you go up to 170!)
There are two things you should be looking into if you need to calculate the factorial function:
1) Memoization. This will dramatically speed up your calculations, since the factorial function has a recursive definition. What you do is cache previous calculations, so when you ask for k!, you can get it in one step by calculating k*((k-1)!) if you have (k-1)! cached.
2) Stirling's approximation. If you need to calculate large factorials, you can approximate them very rapidly this way, and with guaranteed bounds on the error, so you can tell whether the approximation will be acceptably close for your application.
If you do neither of these, you will find that there is some relatively small k for which you simply can't calculate k! in a reasonable amount of time.
Grodriguez is right - this is almost certainly caused by integer overflow.
If you test your method with more modest inputs it appears to return the right output:
public static void main(String[] args) {
Demo obj = new Demo();
for (int i = 0; i < 10; i++)
System.out.println(i + "! = " + obj.factorial(i));
}
500! is massive; when testing your function, starting with smaller inputs would be prudent.
500! is way too big to fit a long, or double.
You would have to use other techniques to get this.
But first, what kind of program needs 500!?
There are some very nice optimization for the implementation of factorizations: see for instance luschny.de for a nice implementation of them in Java. Some require more mathematical insight then others... Have fun with the library :-)

Categories