Eclipse console apparently bugged calculating factorial of 1,000,000 - java

Doing some tests with a friend about the class BigInteger on Java, he made a code that prints "n: " and receive an given number to find its factorial. After some time, I tried to calculate the factorial of 1,000,000, but then (after several minutes of calculations) the console only showed a a lot of zeros, without even the print "n: " that's printed when I run the program and the "n!: " when the result is shown.
In the tests, until 300k, the code was working fine (except for the time to the calculus, but that's under expectations given the numbers). Obs.: the loop is used to separate the lines, since they only support 4096 chars
public static BigInteger zero = new BigInteger("0");
public static BigInteger one = new BigInteger("1");
public static BigInteger minusOne = new BigInteger("-1");
public static BigInteger fat(BigInteger n) {
if(n.equals(zero)) {
return new BigInteger("1");
}
BigInteger i = new BigInteger(n.toString());
while(!i.equals(one)) {
i = i.add(minusOne);
n = n.multiply(i);
}
return new BigInteger(n.toString());
}
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
System.out.print("n: ");
BigInteger bigInt = new BigInteger(in.nextLine());
String bigString = fat(bigInt).toString();
int strSize = bigString.length();
System.out.println("n! = ");
for (int i = 0; i < strSize; i++) {
if((i+1)%4096==0) {
System.out.printf("%c\n",bigString.charAt(i));
}else {
System.out.print(bigString.charAt(i));
}
}
in.close();
}
}
Supposedly there was to happen some output, just not a bunch of zeros and apparently overwriting the first print. Even with large numbers such as 300k, the prints "n: " and "n!: " stayed there. There's no error's messages about Overflow or Stack Overflow. At some point I thought that the console was only showing last part of the number, but asking a friend, he said about some unknown bug of the console or Eclipse (at least for us).

Related

When I run my methods it keeps repeating itself and doesn't move on java

Like the caption said the method "scanInput1" runs two times in a row when it should only run once. Then the method "arrayskapare" runs as intended but after that. instead of running the method "medelvarde" is jumps back and runs "scanInput1" again and again and again
import java.util.*;
class Heltalshanterare{
private static String scanInput1(){
System.out.print("Skriv in antal heltal: ");
Scanner scr = new Scanner(System.in);
String antalHeltal = scr.next();
try {
Integer.parseInt(antalHeltal);
}
catch (NumberFormatException e) {
System.out.println("Ogilitigt värde");
scanInput1();
}
return antalHeltal;
}
private static List<Integer> arrayskapare() {
int antalangivnatal = Integer.parseInt(scanInput1());
int noll = 1;
int heltal = 0;
String tal1 = "";
Scanner tal = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
while (noll <= antalangivnatal) {
noll++;
heltal++;
System.out.print("ange heltal " + heltal + ": ");
tal1 = tal.next();
try {
int num = Integer.parseInt(tal1);
list.add(num);
} catch (NumberFormatException e) {
System.out.println("Ogiltigt värde");
noll--;
heltal--;
}
}
return list;
}
public static int medelvarde(){
int antalsiffror = arrayskapare().size();
int sum = 0;
for (int i : arrayskapare()){sum += i;}
int medelvärde = sum / antalsiffror;
System.out.println("medelvärdet av dina tal är " + medelvärde);
return medelvarde();
}
public static void main(String [] args){
scanInput1();
arrayskapare();
medelvarde();
}
}
Im sorry that the code is so long but I have been struggling with this for too long and I really need some help.
Your main method is calling each method just once, which is what you need. But it's not actually holding onto any of the values being returned. So the number of heltal (integers in English) is captured from the user but then never actually stored anywhere. And later an array of numbers is captured but not stored anywhere.
Your second, bigger problem is that your methods are then calling the earlier methods all over again. So instead of asking the user to type in the data just once, you're forcing them to answer the exact same questions multiple times.
A much tidier approach is to alter your methods so that they take the required data as a parameter. Which means your arrayskapare (array producer) method should take the antalHeltal (number of integers) value as a parameter, and then it won't need to call the scanInput1 method again. Same thing can be done for your medelvarde (mean value) method: have it take the array as a method parameter, so that it won't need to call arrayskapare.
With those changes your main method can simply look like this:
public static void main(String [] args){
int antalHeltal = scanInput1();
List<Integer> heltalArray = arrayskapare(antalHeltal);
int medelvardet = medelvarde(heltalArray);
System.out.println("Medelvärdet är " + medelvardet);
}
Now each method just gets called once and the data captured from the user gets stored into variables and passed along the river of methods until the final result is reached.

This program take lot of time for execution

public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
if(t<1 || t>100){System.exit(0);}
ArrayList a=new ArrayList<>();
for(int i=0;i<t;i++){
String s=in.next().toString();
String s2=in.next().toString();
int count=0;
int first=Integer.parseInt(s);
int last=Integer.parseInt(s2);
if(first<1 || last>1000000000){System.exit(0);}
for(int k=first;k<=last;k++){
int sqrt =(int)Math.sqrt(k);
if(sqrt*sqrt==k){count++;}
}
a.add(count);
}
Iterator it=a.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
In this program when i give big input, it takes lots of time to give output. Can someone tell me how to optimize this program.
this program is for finding square root number.
Input: The first line contains , the number of test cases T. T test cases follow, each in a new line.
Each test case contains two space-separated integers denoting s and s2.
Sample Input
2
3 9
17 24
Sample output
2
0
big input:
35
465868129 988379794
181510012 293922871
395151610 407596310
481403421 520201871
309804254 776824625
304742289 566848910
267554756 828997506
387224568 926504395
244571677 871603971
444567315 582147918
334350264 342469009
400474096 410940967
488907300 943628573
26441071 801576263
182001128 267557939
115732998 974318256
192538332 862327048
45429427 307805497
358658006 842644090
92930998 431601473
231163983 893672132
275221547 298953978
351237326 981399371
484598992 985428966
103405553 529324202
37393469 768655346
30179914 482808626
208821550 538302223
154654533 791652309
68424067 854065374
246956110 517538724
51395253 876949418
57778758 368742600
227566632 606529208
This method compute the number of square between two bounds:
public static int squaredNumberInRange(int lowerBound, int upperBound){
double lowerRoot = Math.sqrt(lowerBound);
double upperRoot = Math.sqrt(upperBound);
lowerRoot = Math.ceil(lowerRoot);
upperRoot = Math.floor(upperRoot);
int spread = (int)upperRoot - (int)lowerRoot + 1;
return spread;
}
Complexity is O(1)

Why can't I print the maximum long value?

I am compiling a Java program using for loop to find out the biggest value of long. However, nothing was printed when I run the program. Why?
Here's my code:
class LongMaxMin {
public static void main(String args[]) {
long i = 0L;
long result = 0L;
for (; ; ) {
result = i++;
if (i<0)
break;
}
System.out.println("The biggest integer:" + result);
}
Mostly because of time.
A long will have a max of about ~9.22 quintillion. You're starting at zero and incrementing up. That means you need to go through 9 quintillion loops before it wraps over and breaks. I just tried to run 2 billion operations in my javascript console and times out for a couple of minutes before I force quit.
If you sit there and let it run long enough, you'll get your output. Alternatively, start i at something close to the max already, like 9,223,372,036,854,700,000, and see if it still gives you the same issues. In Java 8, adding underscore to numeric literals is allowed. Initializing i to something like 9_223_372_036_854_700_000L will give you something in a more timely manner.
The max long is significantly high, at 9.223372e+18. For specifics, 9,223,372,036,854,775,807 is the number in question. This also contributes to that whole "this works, it'll just take WAY too long" theory.
I was curious how long it would take so I wrote a class to do the same thing. Wrote it with a separate thread to update results to the console every 1 second.
"int" results
1,343,211,433 37.4518434691484288634492200 % left
Max Value: 2,147,483,647
Time Taken (seconds): **1.588**
"long" results
1,220,167,357 99.9999999867709190074470400 % left
2,519,937,368 99.9999999726787843108699600 % left
3,881,970,343 99.9999999579115932059510100 % left
5,210,983,861 99.9999999435023997711689800 % left
6,562,562,290 99.9999999288485570811055300 % left
7,853,387,353 99.9999999148534037050721500 % left
9,137,607,100 99.9999999009298653086103000 % left
10,467,975,104 99.9999998865059865071902600 % left
11,813,910,300 99.9999998719133278719112300 % left
13,183,196,499 99.9999998570674971548090400 % left
...it continues on and on...
1,362,032,97 - difference between the 2nd and 3rd values (1 second)
6,771,768,529 seconds - how many seconds it would take to reach long's max value (Long.MAX_VALUE / 2nd3rdDifference)
6,771,768,529 seconds = 214.73 years (per conversion by google search)
So if my calculations are correct...you'd be dead of old age by the time an average computer calculated the max value of long via incrementing and checking if it's overflowed. Your children would be dead to. Your grandchildren, they might be around when it finished...
Code for Max Value Calculation
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
public class MainLongMaxTest {
// /*
public static final long MAX_VALUE = Long.MAX_VALUE;
public static long value = 0;
public static long previousValue = 0;
// */
/*
public static final int MAX_VALUE = Integer.MAX_VALUE;
public static int value = 0;
public static int previousValue = 0;
*/
public static boolean done;
public static BigDecimal startTime;
public static BigDecimal endTime;
public static void main(String[] args) {
Runnable task = new StatusPrinterRunnable();
new Thread(task).start(); // code waits 1 second before result printing loop
done = false;
startTime = new BigDecimal(System.currentTimeMillis());
while(value >= 0) {
previousValue = value;
value += 1;
}
endTime = new BigDecimal(System.currentTimeMillis());
done = true;
}
}
class StatusPrinterRunnable implements Runnable {
public static final NumberFormat numberFormat = NumberFormat.getNumberInstance();
private static long SLEEP_TIME = 1000;
#Override
public void run() {
try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { throw new RuntimeException(e); }
while(!MainLongMaxTest.done) {
long value = MainLongMaxTest.value;
//long valuesLeft = MAX_VALUE - value;
BigDecimal maxValueBd = new BigDecimal(MainLongMaxTest.MAX_VALUE);
BigDecimal valueBd = new BigDecimal(value);
BigDecimal differenceBd = maxValueBd.subtract(valueBd);
BigDecimal percentLeftBd = differenceBd.divide(maxValueBd, 25, RoundingMode.HALF_DOWN);
percentLeftBd = percentLeftBd.multiply(new BigDecimal(100));
String numberAsString = numberFormat.format(value);
String percentLeftAsString = percentLeftBd.toString();
String message = "" + numberAsString + "\t" + percentLeftAsString + " % left";
System.out.println(message);
try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { throw new RuntimeException(e); }
}
BigDecimal msTaken = MainLongMaxTest.endTime.subtract(MainLongMaxTest.startTime);
BigDecimal secondsTaken = msTaken.divide(new BigDecimal("1000"));
System.out.println();
System.out.println("Max Value: " + numberFormat.format(MainLongMaxTest.previousValue));
System.out.println("Time Taken (seconds): " + secondsTaken);
}
}
I think your logic is correct just it will take a lot of time to reach that value.
the maximum Long value can hold is Long.MAX_value which is 9223372036854775807L
to speed up the logic, I modified the program as below and got the expected result.
public static void main(String args[]) {
long i = 9223372036854775806L;
long result = 0L;
for (; ; ) {
result = i++;
if (i<0) {
System.out.println("result"+result);
System.out.println("i"+i);
break;
}
}
System.out.println("The biggest integer: is" + result);
}
Output:
result9223372036854775807
i-9223372036854775808
The biggest integer: is9223372036854775807
result has the maximum value it can hold after that it changes to its minimum value.
You can get the result in one step if you take advantage of binary algebra by:
result = -1L >>> 1;

Math.random called from for loop produces continous "random" numbers

im pretty new to java stuff. At the moment i am trying to write a programm dealing with the birthday problem(wikipedia). I want to know how many people have to be asked for their day and month of birth until one is duplicate.
I wrote a class doing the "asking" with the following code:
public class Starter {
static ArrayList<Integer> peeps = new ArrayList<Integer>();
static boolean match = false;
static int counter = 0;
public static int doRand() {
int rand = (1 + (int) (Math.random() * ((365 - 1) + 1)));
return rand;
}
public static int start() {
do {
int buffer = 0;
buffer = doRand();
if (peeps.isEmpty()) {
peeps.add(doRand());
}
counter++;
for (int i = 0; i < peeps.size(); i++) {
if (peeps.get(i) == buffer) {
match = true;
}
}
peeps.add(buffer);
} while (match == false);
return counter;
}
}
This seems to work and produces numbers somewhat between 10 and 50.
But if I run this function from the following for-loop, I get really strange result:
public class BirtdayProblem {
public static void main(String[] args) {
for (int i=0;i< 1000;i++) {
System.out.println(Starter.start());
}
}
}
It produces an output of 1000 continous numbers...why?
If I run the function multiple times manually, i have never gotten any continous number...
Can someone explain that to me?
Example Output:
25
26
27
...
...
1016
1017
1018
1019
1020
1021
1022
1023
1024
Does not look ver yRandom to me...?
Starter.start() returns the static "counter" value which is incremented by 1 after every iteration in the for loop , hence the output shows the output in increments of 1 .
You are using static member variables for counter and match. That means they belong to the class and will not be reset between calls to start().
Since these variables are used only inside the start() method I suggest you put their declarations there as well.
public static int start() {
boolean match = false;
int counter = 0;
And remove the old declarations at the top.

Format double to at least one significant digit in Java/Android

I have a DecimalFormat object which I'm using to format all of my double values to a set number of digits (let's say 2) when I'm displaying them. I would like it to normally format to 2 decimal places, but I always want at least one significant digit. For example, if my value is 0.2 then my formatter spits out 0.20 and that's great. However, if my value is 0.000034 my formatter will spit out 0.00 and I would prefer my formatter spit out 0.00003.
The number formatters in Objective-C do this very simply, I can just set a max number of digits I want to show at 2 and the minimum number of significant digits at 1 and it produces my desired output, but how can I do it in Java?
I appreciate any help anyone can offer me.
Kyle
Edit: I'm interested in rounding the values so 0.000037 displays as 0.00004.
It's not efficient, so if you perform this operation often I'd try another solution, but if you only call it occasionally this method will work.
import java.text.DecimalFormat;
public class Rounder {
public static void main(String[] args) {
double value = 0.0000037d;
// size to the maximum number of digits you'd like to show
// used to avoid representing the number using scientific notation
// when converting to string
DecimalFormat maxDigitsFormatter = new DecimalFormat("#.###################");
StringBuilder pattern = new StringBuilder().append("0.00");
if(value < 0.01d){
String s = maxDigitsFormatter.format(value);
int i = s.indexOf(".") + 3;
while(i < s.length()-1){
pattern.append("0");
i++;
}
}
DecimalFormat df = new DecimalFormat(pattern.toString());
System.out.println("value = " + value);
System.out.println("formatted value = " + maxDigitsFormatter.format(value));
System.out.println("pattern = " + pattern);
System.out.println("rounded = " + df.format(value));
}
}
import java.math.BigDecimal;
import java.math.MathContext;
public class Test {
public static void main(String[] args) {
String input = 0.000034+"";
//String input = 0.20+"";
int max = 2;
int min =1;
System.out.println(getRes(input,max,min));
}
private static String getRes(String input,int max,int min) {
double x = Double.parseDouble(((new BigDecimal(input)).unscaledValue().intValue()+"").substring(0,min));
int n = (new BigDecimal(input)).scale();
String res = new BigDecimal(x/Math.pow(10,n)).round(MathContext.DECIMAL64).setScale(n).toString();
if(n<max){
for(int i=0;i<max;i++){
res+="0";
}
}
return res;
}
}

Categories

Resources