I'm writing a small program that displays the factorial of a number.
When I enter the number 20 I got the number 2432902008176640000 as result.
How can I limit a decimal number in Java.
For example the number 2432902008176640000 should be 2432 (limit 4).
Thanks in advance.
The following might do what you want, if what you want to do is what I think you want to do:
long n = 2432902008176640000L; // original number
while (n > 9999) {
// while "more than 4 digits", "throw out last digit"
n = n / 10;
}
// now, n = 2432
And a demo.
Notes:
A long can only represent values as large as 9223372036854775807 (which is only about 4 times as large as the number given) before it will overflow. If dealing with larger numbers you'll need to switch to BigInteger or similar. The same technique can be used, updated for syntax differences.
As fge pointed out, this won't work as it is written over negative numbers; this can be addressed by either changing the condition (i.e. n < -9999) or first obtaining the absolute value of n (and then reverting the operation at the end).
As done in yinqiwen's answer, n > 9999 can be replaced with n >= (long)Math.pow(10, N) (preferably using a temporary variable), where N represents the number of decimal digits.
Replace N by the limit.
long v = 2432902008176640000L;
long x = (long) Math.pow(10, N);
while(v >= x)
{
v /= 10;
}
Try this, may help:
Long n = 2432902008176640000;
String num = String.valueOf(n);
num = num.subString(0, 4);
n = Long.valueOf(num);
I am assuming you mean factorial of a number.
Just convert the number into a string and use substring method to get first 4 digits only.
fact is the factorial value
String result_4_str=(fact+"").substring(0, 4);
long result_4 = Long.parseLong(result_4_str);
System.out.println(result_4);
Some of the previous answers with loops are O(n) time complexity. Here's a solution for constant time complexity:
long num = 2432902008176640000L;
int n = 4;
long first_n = (long) (num / Math.pow(10, Math.floor(Math.log10(num)) - n + 1));
You can try
long number = 2432902008176640000L ;
String numberStr = String.valueOf(number);
if(numberStr.length()>=4){
System.out.println(numberStr.substring(0, 4));
}
Related
Not sure if anyone can explain this to me or help me.
I have a 15 Digit Number of which I want to multiply each even number by 2 unless the even number is greater than 9. If it is this needs to be subtracted by 9 to give me an integer that again I can multiply by 2. Once I have all the even numbers multiplied by 2 i need to add them all together with the odd numbers.
Does that make sense.
UPDATE ***
so i have a number say 49209999856459. for that number I am looking to get the even integer so for example the first even one would be 4 then the second would be 2 and so on.
If one of those even numbers are multiplied by 2 then it might be above 9 so I want to subtract 9 to then use the remainder as the even number in its place.
SO !!!
Multiply by 2 the value of each even digit starting from index 0 and then each even index. In each case, if the resulting value is greater than 9, subtract 9 from it (which reduces larger values to a single digit). Leave the values of the digits at the odd indexes unchanged.
public String calculateCheckNumber()
String firstFifteen = longNumber.substring(0,15) ;
int i, checkSum = 0, totalSum = 0;
for (i = 0; i<firstFifteen.length(); i += 2) {
while (i < 9)
i *= 2;
if (i > 9)
i -= 9 ;
}
Was one option I was trying but it honestly I cant seem to get my head around it.
Any Help would be greatly appreciated.
Well, here is one approach. This uses the ternary (?:) operator to condense the operations. Edited base on clarification from the OP. The example you gave is actually a 14 digit string. But the following will work with any number of digits if they start out in a string. If you have a long value, then you can create the character array using:
long v = 49209999856459L;
char[] d = Long.toString(v).toCharArray();
Here is the main algorithm.
String s = "49209999856459";
int sum = 0;
char[] d = s.toCharArray();
for (int i = 0; i < d.length; i++) {
int v = d[i] - '0';
// The even digit will only be greater than 9 after
// doubling if it is >= 5 before.
sum += ((i % 2) == 1) ? v : (v >= 5) ? v+v-9 : v+v;
}
System.out.println(sum);
Prints
86
The problem in question asks to reverse a 32-bit signed integer. Here's the given solution in Java:
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
}
According to the solution's explanation, it's time complexity is O(log10(n)) because there are roughly log10(x) digits in x. Intuitively, there seems to be n-1 iterations of the while loop, where n is the number of digits. (I.E: a 7 digit number requires 6 iterations) However, the solution and given complexity implies that the n is the integer itself and not the number of digits. Can anyone help me gain an intuitive understanding of why the above solution is log10(n) ?
If x is an integer, then floor(log10(x)) + 1 is equal to the number of digits in x.
Let log(10)x = some number y. Then 10^y = x.
For example,
log(10) 10 = 1
log(10) 100 = 2
log(10) 1000 = 3
...
When x is not a perfect power of 10:
floor( log(213) ) = 2
Let me know if this doesn't answer your question.
Let's say the x = 123.
int rev = 0;
rev = rev * 10 + x % 10; // rev = 3, 1st iteration.
x = x/10; // x = 12
rev = rev * 10 + x % 10; // rev = 3 * 10 + 2 = 32, 2nd iteration
x = x/10; // x = 1
rev = rev * 10 + x % 10; // rev = 32 * 10 + 1 = 321, 3rd iteration.
x = 0 so the loop terminates after 3 iterations for 3 digits.
The conditionals within the loop check to see if the reversed values would exceed what a 32 bit number could hold.
So it is log10(n) exactly for the reason you stated in your question. The log of a number n to a given base is the exponent required to raise the base back to the number n. And the exponent is an approximation of the number of digits in the number.
Based on your comment, it could also have been stated that "For any number n, where m is the the number of digits in n, the time complexity is O(m)."
The given reverse algorithm requires in the worst case log_10(x) iterations. In other words, if the given input x consists of k decimal digits, it requires k iterations. But stating that this algorithm is O(log_10(x)) is misleading. This is not logarithmic algorithm. If the input size is not intuitive (for example, testing whether given integer is a prime), we need to rigorously apply the correct definition of input size. In Big O analysis, the input size is defined as the number of characters it takes to write the input. Since we normally encode integers in binary digits, the input size of this algorithm n is approximately log_2 x. Therefore, x is roughly 2^n. The worst case complexity W(x) = log_10 (x) = log_10(2^n) = n log_10(2). Therefore, the big O of reverse algorithm is O(n).
I am working on a Java problem in which I need to check if the second-leading digit of an int (ex: the '2' in 123, or the '8' in 58347) of any size is a particular digit (such as a '2' or a '5'), and then assign true to a Boolean, if it is that digit. I am trying to do the modulo/divisor method, but I am not able to extract the second-leading digit if the number is large.
I searched Stack Overflow, and found a very similar question. However, the solution for that question works if the number is hard-coded as being two digits. I know there is a way by converting int to String, and I tried that method successfully, but I need to use int/modulo/division method. I tried doing (n%100)/10; but it got me second-to-last digit (ex: the '7' in 4562374), not second-after-first digit.
// n is a number such as 123, or 25, or 52856.
while (n > 0) {
int i=((n%10)/10);
if( (i==2)||(i==3) || (i==5)|| (i==7) )
{ secondDigit=true; }
else { secondDigit= false; } }
System.out.println(secondDigit);
Just keep dividing by 10 until the number is < 100 then do modulo 10, example:
class Main {
public static void main(String[] args) {
int n = 58347;
while (n >= 100) {
n /= 10;
}
System.out.println(n % 10); // prints 8
}
}
Not certain about the efficiency of this method, however its easy to read.
Integer.parseInt(String.valueOf(Math.abs(initial_value)).charAt(1)+"")
However, you have to ensure that the number has more than 1 digit.
Instead of repeatedly dividing the number you have until it's small enough for you to handle, how about finding out how big the number is so you only need to do a single division?
What I mean is that you should consider using logarithms to find out the magnitude of your number. Finding the base 10 logarithm of your number gets you its magnitude. For 100 the log_10 is 2, so you can do the following:
long magnitude = Math.log10(number);
long divisor = Math.pow(10, magnitude - 1);
long smallNumber = number / divisor;
int digit = smallNumber % 10;
New to Stackoverflow so please point out anything I can do to improve the quality of my question.
So what my code does (or rather hopes to do) is calculate huge fibonacci numbers modulo a pretty huge m. To make the algorithm more efficient, I employ the use of pisano periods. In essence, I calculate the pisano period of m and then make the calculation of the remainder easier by using the following relation:
The remainder of the n th Fibonacci number (modulo m) is equal to the remainder of the k th Fibonacci number (modulo m) such that k = n % p where p is the pisano period of m.
In order to calculate the pisano period, I use the following property:
If the current Fib % m = 0 and the sum of all Fib's until now % m = 0, then the index of the current Fib is the pisano period of m. (Note the index must be greater than 0)
However I run into a problem in this endeavour: To calculate the pisano period, I have to calculate consecutive Fibonacci numbers. The issue arises when the number of Fibonacci numbers that have to be calculate becomes very large, say 100 000. Then the data type long overflows.
To my knowledge, any endeavour to calculate pisano periods will require the calculation of fibonacci's, so the only solution seems to be to replace long with something else. If anyone has any suggestions as to what this replacement might be, I would greatly appreciate it.
import java.util.*;
public class FibHuge {
public static void main (String [] args) {
Scanner in = new Scanner (System.in);
long num = in.nextLong ();
long mod = in.nextLong();
System.out.println ( getMod(num, mod));
}
private static int getMod (long num, long mod) {
Period per = new Period();
long period = per.getPeriod (mod);
int newFibNum = (int)(num % period);
num = (num % mod);
Integer ia[] = new Integer [per.al.size()];
ia = per.al.toArray (ia);
return ia[newFibNum];
}
}
class Period {
ArrayList <Long> al;
long FNum;
long SNum;
Period () {
al = new ArrayList <Long> ();
FNum = 0;
SNum = 1;
}
private long getFib (long first, long second){
return first + second;
}
long getPeriod (long mod){
boolean bool = true;
long fibcount = 0;
long currentmod = 0;
long fib = 0;
long sum = 0;
while (bool){
if (fibcount <= 1){
currentmod = fibcount % mod;
al.add (currentmod);
sum += fibcount;
}
else {
fib = getFib (FNum, SNum);
FNum = SNum;
SNum = fib;
currentmod = (fib % mod);
al.add (currentmod);
sum += fib;
}
if ( (currentmod == 0 & (sum % mod) == 0) & fibcount > 0){
return fibcount;
}
fibcount++;
}
return mod; //essentially just to satisfy the return condition
}
}
Use BigInteger, but take note that it will be much slower, but with infinite size.
You don't need to use BigInteger unless your modulus is too large to fit into a long in which case I suspect you will run out of memory trying to find the solution.
Instead of calculating the n-th Fibonacci number and then performing a modulus, you can calculate the n-th Fibonacci after modulus using this property
(a + b) % n = (a % n + b % n) % n;
In other words you only need to keep adding the modulus of the number in each iteration. You can save all the modulus values in a Set and when you get a repeated result, you have a period. You can store the iteration number with the result and use this to calculate the period.
In fact modulus is kind of expensive but since you will only ever sum a number which is less than 2 * modulus you can simply do
long c = a + b; // Fibonacci
if (c >= modulus) c -= modulus; // the only real change you need for modulus.
As Java uses a condition move rather than an actual branch this is much faster than using %
I can't think of much more details you need to know without writing the code for you.
I have a question where I have to add numbers from 1 to N which have their set bits as 2. Like for N = 5 we should get value 8, as number 3 and 5 have 2 bits set to one. I am implementing the same in java. I am getting the o/p correct for int value but when it comes to the long values, either it's taking a lot of time or freezing, and when I submit the same on code judge sites, it's giving run time exceeded message. Please guide me how may I optimise my code to run it faster, thanks :)
public static void main(String[] args)
{
long n = 1000000L;
long sum = 0;
long start = System.currentTimeMillis();
for(long i = 1L ; i <= n ; i++)
{
if(Long.bitCount(i) == 2)
{
sum += i;
}
}
long end = System.currentTimeMillis();
System.out.println(sum);
System.out.println("time="+(end-start));
}
As #hbejgel notes, there is no point in looping over all numbers and checking their bit count. You can simply construct numbers with 2 bits and add them up.
You can construct a number with 2 bits by picking two different bit positions in the long, the "higher" bit and the "lower" bit":
long i = (1 << higher) + (1 << lower);
So, you can simply loop over all such numbers, until the value you have constructed exceeds your limit:
long sum = 0;
outer: for (int higher = 1; higher < 63; ++higher) {
for (int lower = 0; lower < higher; ++lower) {
long i = (1 << higher) + (1 << lower);
if (i <= n) {
sum += i;
}
if (i >= n) break outer;
}
}
Let's say we know the closest number, x, equal to or lower than N with 2 set bits, then we can use the formula for power series to quickly sum all positions of the two set bits, for example, if x = b11000, we sum
4*2^0 + S(4)
+ 3*2^1 + S(4) - S(1)
+ 2*2^2 + S(4) - S(2)
+ x
where S(n) = 2 * (1 - 2^n) / (1 - 2)
= 2 + 2^2 + 2^3 ... + 2^n
With numbers encoded 2 out of 5, exactly two bits are set in every one-digit number. The sum is 45, with the exception of N×(N-1)/2 for 0≤N<9.
I think the question is supposed to discover the pattern.
Fast forward. Given a number N, you can tell the largest number
should count by bitmask from the first two bits are set. So you have
a smaller number M
Skip to next counted number Given any number with two bit set, next
largest number is the shift the second bit by one, until underflow.
Skip to next order When underflow happens on set two, shift the
highest bit by one and also the bit on it's right.
You don't really need a loop on N, but the bits it have.
Next question: can you answer a large number? which N >100,000,000
Next Next question: can you answer the same question for X bits when X>2