factorial of non-integer value in java - java

5! = 5*4*3*2*1.
I have no problem with this. But I noticed with my program that if I type in say 3.5! it would return a defined number.
How do you calculate them?
I have something like this in my program
public class fact {
public static void main(String args[]) {
double factorial=1;
System.out.println("Type a number");
double number= sc.nextDouble(); /*I am using scanner*/
while (number !=0 ){
factorial = factorial * number;
number--;
}
System.out.println(factorial);
}
}

Factorial in its normal definition is defined only for positive integers. If you want to calculate factorials for any real numbers, have a look at Gamma functions.
https://en.wikipedia.org/wiki/Gamma_function

Thing is: factorial is pretty simple for whole, positive numbers.
The concept can also be applied for floating point numbers, but the math behind that could be considered advanced.
So: step back; and understand the math behind the concept; before implementing the concept!
In other words; you have to decide whether you intend to change your program to work with int numbers (validated to be > 0 ); or if you intend to allow floating point numbers. If the later is your goal; then your simple implementation won't do any more.
Beyond that: you want to study the concept of floating point numbers in the first place. It is a misconception to assume that a loop like
double number = ...
while (number !=0 ) {
..
number--;
}
would always stop when using floating point numbers instead of int/long! To the contrary ...

You are getting the defined value even for 3.5!, because your code will calculate it as following:
1*3.5*2.5*1.5*0.5
But actually it is wrong value for 3.5!. The correct value is: 11.6317283966. Your method is only valid for integer inputs. See this for more information about decimal factorials:
this link

Related

Cumulative difference with fixed initial value

I'm a newbie to Java and have to implement a solution at work to calculate cumulative difference.
I am extracting data from a flat file using Informatica powercenter. One of the columns is total deductions for a department. The logic required to transform data in this column is below.
If Total deductions<=9999999.99, then display the value as is, ie 9999999.99
If Total deductions>9999999.99, then display 9999999.99 and in the next line display the difference between 9999999.99 and incoming value.
For ex, if incoming value is 10000000.99, then display
9999999.99
1
If total deductions = 20000000.98 then display the below
9999999.99
9999999.99
1
I have the below code where I am hard coding values, and feel like this can be accomplished dynamically.
package day1.examples;
public class MedicalCenter {
public static void main(String[] args) {
double v=9999999.99;
double i=20000000.98;
if (i<v) {
System.out.println(i);
}
if (i>v && i<=9999999.99*2) {
System.out.println(9999999.99);
System.out.println(i-v);
}
if (i>v && i<=9999999.99*3) {
System.out.println(9999999.99);
System.out.println(9999999.99);
System.out.println(i-9999999.99*2);
};
}
}
Sample Output:
9999999.99
9999999.99
1.0
You need to either keep subtracting by 9,999,999.99 until you get the remainder, or you can use division. I'll show you an example of subtraction.
public static void main(String[] args) {
double input; //need to implement this
double v=9999999.99;
while(input > v) {
System.out.print(v + " ");
input -= v; //subtract
}
System.out.println(input);
}
The idea is that you keep subtracting v from the input number until you can't subtract anymore, and each time you subtract you also print out v together with a space. After you're done subtracting, you simply print the remainder of the input.
As far as I know, division is just a glorified form of subtraction in the end, so this is possibly simpler than using division—not only by producing cleaner code (which is often the highest priority), but perhaps also performance wise.
You will have floating point arithmetic issues due to the subtraction however, so you should use BigDecimal instead of double. More information on that here: Is floating point math broken?

Geometric Progression using Recursion (Java)

I have an assignment for class where I need to write a method which calculates a Geometric progression for n integers using recursion.
The value of n is received from the user.
public static float Geometric(float n)
{
if(n==0)
return 1;
else
{
if(n == 1)
System.out.println(n);
else
return (n * Geometric(n-1));
}
}
The code works fine, until the value of n exceeds 34. Then, the method starts returning wrong answers. I'm assuming it has to do with the maximum value that a float can hold.
Is there a way to calculate/store values that exceed the maximum value of the primitive data types?
It seems to me that recursion isn't a good way to calculate a geometric progression, but maybe I'm just missing something. Any suggestions?
Thanks!
Welcome to StackOverflow!
For dealing with massive numbers, you can try looking at BigDecimal or BigInteger class. There is also another StackOverflow question (Finding the factorial using recursion with the BigInteger Class) that should be quite similar to your case

How can I reduce iterations in for loop that takes to much time for execution?

Here, I am finding number of perfect square numbers in given range.
But I am dealing with 'for' loop execution that takes much time for execution.
The index/key traverses from two numbers, lets say A to B, and does some operation in for loop.
The problem arises when there's large difference between A and B (e.g. A = 2 & B = 100000)
Can u suggest how can I reduce or optimize the execution time?
Scanner in = new Scanner(System.in);
int A = in.nextInt();
int B = in.nextInt();
int cnt = 0;
for(int number =A ; number<= B; number++){
int sqrt = (int) Math.sqrt(number);
if(sqrt*sqrt == number) {
cnt++;
}
}
System.out.println(cnt);
Or is it because of Math class operations that takes too much time to execute?
Can you suggest any alternate approach to find the square numbers between given range?
Thanks in advance!
I found an alternate way to find the count of perfect square numbers between given range.
This can be simply achieve by using Math.floor and Math.ceil operations.
Math.floor(Math.sqrt(B)) - Math.ceil(Math.sqrt(A)) + 1
Thanks! :)
Instead of going through each number in the range and figuring out if its a perfect square, I would suggest the below
Find a square root of the start number and find the integer part of it.
Lets say start number is 5. So integer part of the square root will be 2.
Now do the same for the range end number
Lets say end range was 1000, so the integer part of its square root would be 31. Now iterate from 2+1 to 31 and keep printing its square. That would give you the perfect squares between the given range.
Instead of the if(sqrt * sqrt == number) you could also check whether the double returned by Math.srt(number) is a integer. The algorithm would than become as follows:
for(int number =A ; number<= B; number++){
if((Math.sqrt(number) % 1) == 0) {
cnt++;
}
}
Note: Haven't tried the code myself so might not work as I expect.
Regarding the question on how you can improve the performance. The checking on whether the number is perfect could be done in parallel by executing per number a task. The access to the counter has to be synchronized than, (to be on the safe side).

Project Euler #8 in java

The challenge is listed here:
The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?
I have written a code that works with the given 4 digit example, but doesn't work for 13 digits. I suspect there is some type of data overflow, but I am unsure. My super inefficient code is below.
public class Euler8 {
public static void main(String[]args){
String num = "/*number listed above*/";
int n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13;
long sum=0, newSum;
for(int n=0; n<=987; n++){
n1=Character.getNumericValue(num.charAt(n));
n2=Character.getNumericValue(num.charAt(n+1));
n3=Character.getNumericValue(num.charAt(n+2));
n4=Character.getNumericValue(num.charAt(n+3));
n5=Character.getNumericValue(num.charAt(n+4));
n6=Character.getNumericValue(num.charAt(n+5));
n7=Character.getNumericValue(num.charAt(n+6));
n8=Character.getNumericValue(num.charAt(n+7));
n9=Character.getNumericValue(num.charAt(n+8));
n10=Character.getNumericValue(num.charAt(n+9));
n11=Character.getNumericValue(num.charAt(n+10));
n12=Character.getNumericValue(num.charAt(n+11));
n13=Character.getNumericValue(num.charAt(n+12));
newSum= (long)(n1*n2*n3*n4*n5*n6*n7*n8*n9*n10*n11*n12*n13);
if(newSum>=sum)
sum=newSum;
}
System.out.println(sum);
}
}
My code outputs this number:
2091059712
Your code makes a cast to long too late: by the time the cast is performed, the multiplication has been completed in 32-bit integers, predictably causing an overflow.
Change the code as follows to fix the problem:
// newSum should be called newProd, because you use multiplication, not addition
newSum= ((long)n1)*n2*n3*n4*n5*n6*n7*n8*n9*n10*n11*n12*n13;
Note that your algorithm is not the most efficient: you could do it 13 times faster if you observe that the product for positions i+1..i+13 can be computed from the product for positions i..i+12 by dividing the value at position i and multiplying by the value at position i+13.
Of course you would have to be careful not to divide by zero. You can work around this by observing that any time you encounter a zero, the next 13 products would all be zero, so you could simply skip them, and move on to the next "train" of non-zeros.
The problem is that n1*n2*n3*n4*n5*n6*n7*n8*n9*n10*n11*n12*n13 overflows because:
they are all int variables, and
an int multiplied by an int gives an int.
The typecase to long is applied to the entire product, and (therefore) happens too late to cause the computations to be done with long arithmetic and avoid the overflow problem.
The simple solution to that particular problem is to declare the n variables as long. It is possible that #dasblinkelights' code (casting n1) is faster ... but you would need to benchmark it to be sure. And there are more significant optimizations than that.
I get the answer as 23514624000 . which is actually correct.
public class LargestProduct {
public static void main(String[]args) {
String s="7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
long k=0,l=13,ans=1,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13;
long Max_Num=0;
String[] result=new String[1000];
result=s.split("");
for(int i=0;i<=987;i++) {
n1=Integer.parseInt(result[i]);
n2=Integer.parseInt(result[i+1]);
n3=Integer.parseInt(result[i+2]);
n4=Integer.parseInt(result[i+3]);
n5=Integer.parseInt(result[i+4]);
n6=Integer.parseInt(result[i+5]);
n7=Integer.parseInt(result[i+6]);
n8=Integer.parseInt(result[i+7]);
n9=Integer.parseInt(result[i+8]);
n10=Integer.parseInt(result[i+9]);
n11=Integer.parseInt(result[i+10]);
n12=Integer.parseInt(result[i+11]);
n13=Integer.parseInt(result[i+12]);
ans=n1*n2*n3*n4*n5*n6*n7*n8*n9*n10*n11*n12*n13;
Max_Num=Math.max(Max_Num, ans);
}
System.out.println(Max_Num);
}
}

Convert fraction to decimal number

i'm doing some exercises in my Java book. I'm very new to programming. Therefore, notice (in the code) that i'm still on Chapter one. Now I already did everything, I just want a confirmation if this is legitimate so I can feel free to move on next.
If not, I would sincerely appreciate to not do my code for me; I want advice.
Here's the question written in the book,
"Write an application that prompts/reads the numerator and denominator of a fraction as integers, then prints the decimal equivalent of the fraction."
I'll illustrate this sentence with my code:
I did a revision here. Is this one OK?..
import java.util.*;
public class ExerciseEleven {
public static void main (String[] args) {
Scanner sc = new Scanner (System.in);
double fraction;
int fractionValue;
int decimal;
double value;
System.out.println("Enter Numerator: ");
int numerator = sc.nextInt();
System.out.println("Enter Denominator: ");
int denominator = sc.nextInt();
fraction = (double) numerator / denominator;
fractionValue = (int) (fraction * 10);
decimal = fractionValue % 10;
value = decimal * 0.1;
System.out.println(value);
}
}
It compiles and works fine.
Thank you.
It doesn't do what task says it should. You read doubles instead of integers, and the decimal equivalent is not what you print out. Decimal equivalent for 1/2 is 0.5. And you print 5.
Also, you can pay attention to your code style: variable names are usually written in lowerCamelCase, like that : simpleVariable.
Update
now it prints what you need. However you do it not in the very right way and your indentation can still be improved.
It's fine (I didn't read the assignment very well, did I? Kudos to Vladimir.) ...but some comments:
Usually you want to indent methods within the class.
Standard practice is to use initial caps (Numerator) only for types (e.g., classes, interfaces, enums). Variable, field, and method names should start with a lower-case letter. Now, you're free to ignore standard practice, but if you do people will have a lot of trouble reading your code. :-)
For rounding, you probably want to look at Math.round rather than truncating with a cast. But the assignment didn't say anything about rounding.
You might want to handle the case where denominator is zero.
So keeping those in mind:
import java.util.*;
public class ExcerciseEleven {
public static void main (String[] args) {
Scanner sc = new Scanner (System.in);
System.out.println("Enter Numerator: ");
int numerator = sc.nextInt();
System.out.println("Enter Denominator: ");
int denominator = sc.nextInt();
if (denominator == 0) {
System.out.println("Can't divide by zero");
}
else {
double fraction = (double)numerator / denominator;
System.out.println(fraction);
}
}
}
Hey I am doing some thinking about this and I have noticed something interesting after looking at this source and here is the Algorithm that I plan on implementing
First I will convert the number from the Metric using the
Javax.Measure family of functions and I will get a number like
0.3750
Then I will divide the number by ONE_SIXTEENTH which = 0.0625
ONE_SIXTEENTH = 0.0625
The answer 0.3750 / ONE_SIXTEENTH = 6;
So now I know there are 6 sixteenths of the inch
Next I check to see if 6 is divisible by 4, 6/4 = 1.5 ie not a whole number so the fraction is still regarded as 6/16th of an inch for now
Next I check to see if 6 is divisible by 2, 6/2 = 3
This is a whole number so we will use it to reconstitute the fraction
So now that we have divided 6 by 2 and gotten 3 the 16 needs to be divided by 2 and we end up with 8 so 6/16th of an inch becomes 3/8th of an inch.
PS Has anyone noticed that this is similar to a fizz bang program?
____________________________________________
Here is the chart which helped me get my head around this
My workings
There are three important parts of division operation :
Sign of the result.
Integral part
Decimal part
Also, there are few corner cases where you need to deal with the fact that Integer.MIN_VALUE is greater than Integer.MAX_VALUE when compared in absolute form.
For example : -2147483648/-1 can't yield 2147483648 when divided in the form of integer types. The reason is simple. The type of the resulting type will be integer type, and the maximum positive value that a integer type variable can hold is +2147483647
To mitigate that scenario, we should at first convert both the numerator and denominator into their long positive form. That gives us the integral part of the answer.
The XOR of two numbers will have the sign bit as 1 only in case they have opposite signs. That solves the first part (sign of result) of the problem.
For decimal part, we can employ the general division rule i.e. multiply the remainder with 10 and try dividing again and repeat. Keep record of the remainder we have already come across to prevent the loop from going into unbounded iterations.
public String fractionToDecimal(int A, int B) {
StringBuilder sb = new StringBuilder((A^B) < 0 ? "-" : "");
long a = Math.abs((long)A);
long b = Math.abs((long)B);
sb.append(Long.toString(a/b));
long rem = a % b;
sb.append((rem != 0) ? "." : "");
Map<Long, Integer> remainderMap = new HashMap<>();
int pos = 0;
while (rem != 0){
sb.append(Long.toString((rem*10)/b));
remainderMap.put(rem, pos++);
rem = (rem*10) % b;
if (remainderMap.containsKey(rem)){
String currNum[] = sb.toString().split("\\.");
return currNum[0] + "." + currNum[1].substring(0, remainderMap.get(rem)) +
"(" + currNum[1].substring(remainderMap.get(rem)) + ")";
}
}
if (sb.toString().equals("-0")) return "0";
return sb.toString();
}
Sample output :
2/3 gives 0.(6)
-2147483648/-1 gives 2147483648

Categories

Resources