I need to find the number of digits of very large multiplications (about 300 digits each). I was wondering if there is a trick to predict the number of digits that the product will be without actually performing the calculation.
The number of digits can be calculated exactly by the rounded (down) sum of the base 10 log of the two multiplicands plus 1, as follows:
public static void main(String[] args) {
DecimalFormat f = new DecimalFormat("#");
double num1 = 12345678901234567890d;
double num2 = 314159265358979d;
// Here's the line that does the work:
int numberOfDigits = (int) (Math.log10(num1) + Math.log10(num2)) + 1;
System.out.println(f.format(num1) + " * " + f.format(num2) + " = " +
f.format((num1 * num2)) + ", which has " + numberOfDigits + " digits");
}
Output:
12345678901234567000 * 314159265358979 = 3878509413969699000000000000000000, which has 34 digits
This will work for arbitrarily large numbers.
Cristobalito's answer pretty much gets it. Let me make the "about" more precise:
Suppose the first number has n digits, and the second has m. The lowest they could be is 10^(n-1) and 10^(m-1) respectively. That product would the lowest it could be, and would be 10^(m+n-2), which is m+n-1 digits.
The highest they could be is 10^n - 1 and 10^m - 1 respectively. That product would be the highest it could be, and would be 10^(n+m) - 10^n - 10^m + 1, which has at most m+n digits.
Thus if you are multiplying an n-digit number by an m-digit number, the product will have either m+n-1 or m+n digits.
Similar logic holds for other bases, such as base 2.
Related
I am doing the following exercise: The number of digits of a power of 2.. The statement is:
What is the number of digits of a power of 2?
2 ---> 1 digit
2 * 2 = 4 ---> 1 digit
2 * 2 * 2 = 8 ---> 1 digit
2 * 2 * 2 * 2 = 16 ---> 2 digits
... ... ... 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 = 1024 ---> 4 digits
Then, given the exponent, what would be the number of digits of
that power?
I have tried the following answer:
import java.math.BigInteger;
public class Power {
public static long digit(long exp) {
System.out.println("exp: "+exp);
BigInteger pow = BigInteger.valueOf(2).pow((int)exp);
return String.valueOf(pow).split("").length;
}
}
However it times out with big exponents like: 562078812
How could we improve this solution? Is there any fastest answer?
I have also read:
https://www.geeksforgeeks.org/biginteger-pow-method-in-java/
BigInteger.pow(BigInteger)?
Infinite Loop During Calculation of Power of Big Integers Java
The fastest answer is to use math.
The number of digits in 2^n is (nlog₁₀2)+1 .
You can achieve that by simply returning n * Math.log10(2) + 1. Good luck.
In decimal system, there will be exactly (n+1) digits in 10 power n.
10 power 1 has 2 digits.
10 power 2 has 3 digits.
10 power 3 has 4 digits.
...
.....
10 power n has (n+1) digits.
The trick here is to find number of decimal digits in the exponent of '2'.
The difficult way to find the answer is to actually calculate 2 power n and then count the number of digits. However, this method requires huge computing power.
The simpler answer lies in the difference between 10 and 2.
If power of 2 raises by 1 in binary system, then digits in decimal system raise only by log 2 base 10!
For a raise of n powers in binary, the equivalent will be
(n *log2_base_10 + 1) in decimal system.
Working solution:
public class Power {
public static long digit(long exp) {
return (long) (Math.ceil(exp * Math.log10(2)) + 1);
}
public static void main(String[] args) {
long exp = 50000000;
System.out.println("Number of digits in 2 power " + exp
+ " = " + Power.digit(50000000));
}
}
Output:
$ javac Power.java
$ java Power
Number of digits in 2 power 50000000 = 15051501
Use static method like below to compute number of digits. I think this is faster way
static int countDigits(int n)
{
return (int)(n * Math.log10(2) + 1);
}
This question already has answers here:
Java Math.pow(a,b) time complexity
(2 answers)
Closed 4 years ago.
public class HelloWorld{
public static void main(String []args){
int orig=103, reverse=0, mod;
int numOfDigits=0;
int n = orig;
while (n>0){
n /= 10;
numOfDigits++;
}
n = orig;
while (n > 0){
mod = n % 10;
reverse = reverse + (int)(mod * java.lang.Math.pow(10, numOfDigits-1));
numOfDigits--;
n /= 10;
}
System.out.println("Reversed is : " + reverse);
}
}
I do know that reverse = reverse + (int)(mod * java.lang.Math.pow(10, numOfDigits-1)); can be replaced by reverse = mod + (reverse*10).
Was wondering if I had just increased the complexity of a simple program by calculating total number of digits and applying power?
P.S: Kindly assume that orig can be taken as an input from the user and could be a number of any number of digits. I have hard coded only for experiment.
You didn't increase the complexity ... but you did make it slower. The expression pow(10, numOfDigits - 1) will be substantially slower than reverse = mod + (reverse * 10)
It is also possible that a computation that uses Math.pow instead of integer multiplication is inaccurate due to floating point imprecision. A double has only 52 bits of precision, compared with 63 for a long. In this example, this probably doesn't apply, but it is something to be wary of, in general
Probably, this would be the best approach with less iteration & complexity:
public class NumReverse {
public long reverseNumber(long number){
long reverse = 0;
while(number != 0){
reverse = (reverse*10)+(number%10);
number = number/10;
}
return reverse;
}
public static void main(String a[]){
System.out.println("Reversed is: "+new NumReverse().reverseNumber(103));
}
}
compute the multiply times and add times:
suppose f(x) = an * x^n + an-1 * x^n-1 + ... + a1 * x + a0
1. If calculate f(x) by computing one item by one item,
it will take (n+1) + n + (n-1) + ... + 1 + 0 = (n+1)(n+2)/2 multiply times and n addition times.
2. If calculate f(x) by n = n*10 + mod,
it will take n multiply times and n addition times.
Of course, if pow() has some optimization such as "divide and conquer", the complexity of pow() should be O(logN).
I am trying to split a number of a base then separating the two numbers to get different outputs. (Keep in mind I just edited, my answer is the solution). This is left here so people that have a similar problem can find a solution. Thank you all!
So this is the idea:
If number >= 10 && of base 10
Then give me discounted price on 10 units
if number <= 0 && not base 10
Then add the discount for the number which has 10 units in it and the remainder without the discount (let's say 100% for simplicity sake of the numbers)
So to make a practical example
If I order 25 units of x (at $1 each) and 15 units (at $1 each) of y the price will be:
x 20 units = $0
x 5 units = $5 total
y 10 units = $0
y 5 units = $5 total
This is a bit tricky and this is what I got so far:
double discountedmNI = (mNI - ((mNI/100)*10)) * mNIC;
double discountedmNIP = mNI - ((mNI/100)*10);
if(mNIC >= 10 && mNIC % 10 == 0){
System.out.println("mNI " + discountedmNIP + " " + mNIC);
System.out.println(discountedmNI);
}
else if (!mNIC % 10 == 0){
System.out.println("mNI " + mNI + mNIC);
System.out.println(mNI * mNIC);
}
I don't think I am defining separate the 10 units right
Thank you all!
I hope I understood you right. I get that you want to calculate a total price that consists of two elements: the price for non-discounted items and a price for discounted items.
// The following three values are just example assumptions.
float discountInPercent = 100.0f;
float itemsOrdered = 5004.0f;
float itemPriceNormal = 5.0f;
// Here the price for one discounted item gets calculated.
// Please remember that the discount is given in percentage.
float itemPriceDiscounted = itemPriceNormal * ((100.0f - discountInPercent) / 100.0f);
// Calculate the count of items that get discounted and those that
// will get priced normally.
float itemsDiscounted = Math.floor(itemsOrdered / 10.0f);
float itemsNotDiscounted = itemsOrdered % 10;
// Finally calculate the two elements of the total price and sum it up.
float priceDiscounted = (itemsDiscounted * itemPriceDiscounted);
float priceNormal = (itemsNotDiscounted * itemPriceNormal);
float totalPrice = priceDiscounted + priceNormal;
System.out.println("Price discounted: %.2f" + priceDiscounted);
System.out.println("Price non-discounted: %.2f" + priceNormal);
System.out.println("Price total: %.2f" + totalPrice);
EUREKA!
double discountedmNIP = mNI - ((mNI/100)*10);
int mNIC2 = (mNIC % 10);
double mNIC2disc = (mNI * mNIC2);
double discountedmNI = (mNI - ((mNI/100)*10)) * (mNIC - mNIC2);
if(mNIC >= 10){
System.out.println(discountedmNIP + " " + (mNIC - mNIC2) + " " + discountedmNI );
System.out.println(mNI + " " + mNIC2 + " " + mNIC2disc);
}
else{
System.out.print(mNI + " " + mNIC);
System.out.print(mNI * mNIC);
}
double sum = (mNI + discountedmNI + discountedRh + rH);
System.out.println('\t');
System.out.println("Total order cost " + sum);
All I need to do is to take the units % 10 which will divide the left side integer or double by the right side (left side input from user)
and will give me the remainder when I do that variable subtracted to the original variable!
Again, this small step took me a whole night to figure it out, and is simple indeed. This is for a class, and if you are in that class and you are reading (even though you might have to dig a little to find what assignment is this one), I would just like to tell you this is what's fun about programming! I am not being sarcastic I really love these type of problems!
Signed:
That foreign guy;
EUREKA again!
Enjoy!
Been searching here and google for a couple of days as well as asking my programming friends.
Unfortunately, i still don't understand how to change my code...
My program calculates the factorial of a given number. It then provides a number which represents how many digits the factorials answer includes. Then it sums the values of those digits together to give a total.
My program works for any number between 1! and 31!... If you put in anything over 31! (for example 50! or 100!) it doesn't work and just throws back minus numbers and no total.
I was hoping you guys could point me in the right direction or give me some advice.
I understand using BigIntegers maybe a solution however i don't understand them personally, hence coming here.
Any help would be much appreciated. Thanks.
package java20;
/**
* Program to calculate the factorial of a given number.
* Once implemented, it will calculate how many digits the answer includes.
* It will then sum these digits together to provide a total.
* #author shardy
* date: 30/09/2012
*/
//import java.math.BigInteger;
public class Java20 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
//Using given number stored in factorialNo, calculates factorial
//currently only works for numbers between 1! and 31! :(
int fact= 1;
int factorialNo = 10;
for (int i = 1; i <= factorialNo; i++)
{
fact=fact*i;
}
System.out.println("The factorial of " + factorialNo +
" (or " + factorialNo + "!) is: " + fact);
//Using answer stored in fact, calculates how many digits the answer has
final int answerNo = fact;
final int digits = 1 + (int)Math.floor(Math.log10(answerNo));
System.out.println("The number of digits in the factorials "
+ "answer is: " + digits);
//Using remainders, calculates each digits value and sums them together
int number = fact;
int reminder;
int sum = 0;
while(number>=1)
{
reminder=number%10;
sum=sum+reminder;
number=number/10;
}
System.out.println("The total sum of all the " + digits
+ " idividual digits from the answer of the factorial of "
+ factorialNo + " is: " + sum);
}
}
You can use BigInteger in java, it has as much numbers as you want
BigInteger fact= BigInteger.ONE;
int factorialNo = 10;
for (int i = 2; i <= factorialNo; i++){
fact = fact.multiply(new BigInteger(String.valueOf(i)));
}
System.out.println("The factorial of " + factorialNo +
" (or " + factorialNo + "!) is: " + fact);
final int digits = fact.toString().length();
BigInteger number = new BigInteger(fact.toString());
BigInteger reminder;
BigInteger sum = BigInteger.ZERO;
BigInteger ten = new BigInteger(String.valueOf(10));
while(number.compareTo(BigInteger.ONE)>=0)
{
reminder=number.mod(ten);
sum=sum.add(reminder);
number=number.divide(ten);
}
System.out.println("The total sum of all the " + digits
+ " idividual digits from the answer of the factorial of "
+ factorialNo + " is: " + sum
EDIT: the code is improved to be compatible with author's code
If you put in anything over 31! (for example 50! or 100!) it doesn't
work and just throws back minus numbers and no total.
This is because primitive integer types are subject to overflow when you exceed their maximum possible value. Which computing factorials has a tendency to do.
I was hoping you guys could point me in the right direction or give me
some advice. I understand using BigIntegers maybe a solution however i
don't understand them personally, hence coming here.
You are correct that using BigInteger is one possible solution. You can, for instance, do something like:
public BigInteger factorial(int num) {
if (num < 0) {
throw new IllegalArgumentException("Not today!");
}
BigInteger result = BigInteger.ONE;
for (int next = 2; next <= num; next++) {
result = result.multiply(new BigInteger(Integer.toString(next, 10)));
}
return result;
}
If you're calculating things like (m!/n!), you are better off using logarithms of factorials.
You should also consider these two improvements:
Memoize, don't recalculate. Store those hard-earned values once you calculate them.
You should be using the gamma function to calculate factorials. The way you're doing it with a loop is the naive thing that is presented to students. There's a nice implementation of ln(gamma(x)) in Numerical Recipes.
You can always use BigDecimal if you must, but it's a last resort. You should still consider these points.
There's a gamma function implementation available from Apache Commons. The source code might not be as familiar as the naive approach, but if you see how it's done it'll be obvious that it's more efficient even for moderate arguments.
From Java Malik textbook- determine if an number is divisible by 11..
Code Solution provided:
import java.util.*;
public class Divby11
{
static Scanner console = new Scanner(System.in);
public static void main (String[] args)
{
int num, temp, sum;
char sign;
System.out.print("Enter a positive integer: ");
num = console.nextInt();
System.out.println();
temp = num;
sum = 0;
sign = '+';
do
{
switch (sign)
{
case '+' :
sum = sum + num % 10;
sign = '-';
break;
case '-' :
sum = sum - num % 10;
sign = '+';
}
num = num / 10; //remove the last digit
}
while (num > 0);
if (sum % 11 == 0)
System.out.println(temp + " is divisible by 11");
else
System.out.println(temp + " is not divisible by 11");
}
Why go through all the effort above and just say...
if (sum % 11 == 0)
System.out.println(temp + " is divisible by 11");
else
System.out.println(temp + " is not divisible by 11");
Can any of you experts see why the author would do it this way (long way)?
for the Divisibility Rule of 11:
form the alternating sum of the digits
if this sum is divisible for 11 then the number is divisible for 11
Examples
68090 = 0 - 9 + 0 - 8 + 6 = -11 => TRUE
493827 = 7 - 2 + 8 - 3 + 9 - 4 = 15 = 4 => FALSE
This code example isn't actually dividing by eleven. If you see, it's alternating between adding and subtracting each digit, then checks at the very end if the result is divisible by 11.
For example, look at the following number and how this algorithm works with it:
Start with sum=0, sign='+', num=517
First iteration: sum=7, sign='-', num=51
Second iteration: sum=6, sign='+', num=5
Final iteration: sum=11, sign='-', num=0
The final result is divisible by eleven.
EDIT: The algorithm does indeed look to be implementing the divisibility rule for 11 as dfa mentions in his answer.
You will have to provide more context from the book as to what the author was trying to demonstrate. This code example does not check to see if the number entered is divisible by 11. What it does is it adds every other digit, subtracts every other digit and then checks THAT number to see if it's divisible by 10.
EX
Entered number is 4938
It takes the 8 adds it to sum
Divides by ten giving 493
Takes the 3 subtracts it from sum: sum = 5
Divides by ten giving 49
Takes 9 and adds it to sum: sum = 14
Divides by ten giving 4
Takes 4 subtracts it from sum: sum = 10
THEN it checks if this is divisible by 11.
Ok, I know why now. He/she's trying to teach you something besides computing about numbers
I suspect it is simulating the manual test that digits in the odd positions and the digits in the even positions differ by a factor of 11. In practice using %11 would be the way to go.
EDIT: If the example were truly trying to avoid doing % 11, it should send the sum through again until it is 0.
It an example to show how to implement that particular check. Using your example would not demonstrate the same code methodologies.