Why is this code giving me a strange output - java

The method below was written to make a String version of a number, I know there are already methods that do this, such as String.valueOf(), Double.toString(), or even just "" + someNumber.
private static String numToString(double i) {
String revNumber = "";
boolean isNeg = false;
if (i == 0) { //catch zero case
return "0";
}
if (i < 0) {
isNeg = true;
}
i = Math.abs(i);
while (i > 0) { //loop backwards through number, this loop
//finish, otherwise, i would not get any output in 'main()'
revNumber += "" + i % 10; //get the end
i /= 10; //slice end
}
String number = ""; //reversed
for (int k = revNumber.length() - 1; k >= 0; k--) {
number += revNumber.substring(k, k + 1);
}
revNumber = null; //let gc do its work
return isNeg ? "-" + number : number; //result expression to add "-"
//if needed.
}
Although the above method should only be used for ints (32-bit), I made it accept a double (64-bit) argument and I passed a double argument, without a decimal, the output results are the same if I pass an int into the method as well, or with a decimals, etc...
Test:
public static void main(String[] args) {
double test = -134; //Passing double arg
System.out.println(numToString(test)); //results
}
Result: (Maximum memory results for double?):
-323-E5.1223-E33.1123-E43.1023-E43.1913-E43.1813-E43.1713-E43.1613-E43.1513-E43.1413-E43.1313-E43.1213-E43.1113-E43.1013-E43.1903-E43.1803-E999999999999933.1703-E999999999999933.1603-E999999999999933.1503-E999999999999933.1403-E9899999999999933.1303-E999999999999933.1203-E999999999999933.1103-E8899999999999933.1003-E9899999999999933.1992-E999999999999933.1892-E999999999999933.1792-E999999999999933.1692-E999999999999933.1592-E999999999999933.1492-E999999999999933.1392-E999999999999933.1292-E999999999999933.1192-E999999999999933.1092-E999999999999933.1982-E999999999999933.1882-E1999999999999933.1782-E999999999999933.1682-E999999999999933.1582-E999999999999933.1482-E999999999999933.1382-E999999999999933.1282-E1999999999999933.1182-E1999999999999933.1082-E2999999999999933.1972-E2999999999999933.1872-E3999999999999933.1772-E2999999999999933.1672-E1999999999999933.1572-E2999999999999933.1472-E999999999999933.1372-E999999999999933.1272-E1999999999999933.1172-E2999999999999933.1072-E2999999999999933.1962-E1999999999999933.1862-E999999999999933.1762-E999999999999933.1662-E999999999999933.1562-E999999999999933.1462-E999999999999933.1362-E999999999999933.1262-E999999999999933.1162-E999999999999933.1062-E999999999999933.1952-E999999999999933.1852-E999999999999933.1752-E999999999999933.1652-E999999999999933.1552-E999999999999933.1452-E999999999999933.1352-E999999999999933.1252-E999999999999933.1152-E999999999999933.1052-E9899999999999933.1942-E9899999999999933.1842-E999999999999933.1742-E999999999999933.1642-E999999999999933.1542-E999999999999933.1442-E999999999999933.1342-E999999999999933.1242-E999999999999933.1142-E9899999999999933.1042-E999999999999933.1932-E8899999999999933.1832-E9899999999999933.1732-E8899999999999933.1632-E8899999999999933.1532-E8899999999999933.1432-E999999999999933.1332-E9899999999999933.1232-E8899999999999933.1132-E7899999999999933.1032-E8899999999999933.1922-E8899999999999933.1822-E7899999999999933.1722-E6899999999999933.1622-E5899999999999933.1522-E5899999999999933.1422-E6899999999999933.1322-E6899999999999933.1222-E6899999999999933.1122-E7899999999999933.1022-E7899999999999933.1912-E7899999999999933.1812-E8899999999999933.1712-E8899999999999933.1612-E7899999999999933.1512-E7899999999999933.1412-E6899999999999933.1312-E6899999999999933.1212-E7899999999999933.1112-E7899999999999933.1012-E7899999999999933.1902-E7899999999999933.1802-E6899999999999933.1702-E7899999999999933.1602-E7899999999999933.1502-E8899999999999933.1402-E8899999999999933.1302-E8899999999999933.1202-E8899999999999933.1102-E7899999999999933.1002-E7899999999999933.1991-E9899999999999933.1891-E9899999999999933.1791-E8899999999999933.1691-E7899999999999933.1591-E8899999999999933.1491-E8899999999999933.1391-E999999999999933.1291-E9899999999999933.1191-E9899999999999933.1091-E999999999999933.1981-E999999999999933.1881-E999999999999933.1781-E999999999999933.1681-E999999999999933.1581-E1999999999999933.1481-E999999999999933.1381-E999999999999933.1281-E1999999999999933.1181-E2999999999999933.1081-E999999999999933.1971-E1999999999999933.1871-E999999999999933.1771-E2999999999999933.1671-E3999999999999933.1571-E3999999999999933.1471-E2999999999999933.1371-E2999999999999933.1271-E2999999999999933.1171-E999999999999933.1071-E999999999999933.1961-E999999999999933.1861-E999999999999933.1761-E999999999999933.1661-E999999999999933.1561-E999999999999933.1461-E8899999999999933.1361-E8899999999999933.1261-E8899999999999933.1161-E7899999999999933.1061-E7899999999999933.1951-E7899999999999933.1851-E7899999999999933.1751-E7899999999999933.1651-E7899999999999933.1551-E6899999999999933.1451-E6899999999999933.1351-E6899999999999933.1251-E6899999999999933.1151-E6899999999999933.1051-E7899999999999933.1941-E6899999999999933.1841-E7899999999999933.1741-E7899999999999933.1641-E9899999999999933.1541-E999999999999933.1441-E999999999999933.1341-E999999999999933.1241-E999999999999933.1141-E999999999999933.1041-E999999999999933.1931-E9899999999999933.1831-E999999999999933.1731-E999999999999933.1631-E8899999999999933.1531-E9899999999999933.1431-E9899999999999933.1331-E8899999999999933.1231-E8899999999999933.1131-E8899999999999933.1031-E7899999999999933.1921-E7899999999999933.1821-E7899999999999933.1721-E6899999999999933.1621-E7899999999999933.1521-E7899999999999933.1421-E8899999999999933.1321-E7899999999999933.1221-E7899999999999933.1121-E8899999999999933.1021-E8899999999999933.1911-E9899999999999933.1811-E999999999999933.1711-E999999999999933.1611-E999999999999933.1511-E999999999999933.1411-E1999999999999933.1311-E2999999999999933.1211-E3999999999999933.1111-E2999999999999933.1011-E2999999999999933.1901-E3999999999999933.1801-E2999999999999933.1701-E2999999999999933.1601-E3999999999999933.1501-E2999999999999933.1401-E3999999999999933.1301-E3999999999999933.1201-E4999999999999933.1101-E5999999999999933.1001-E4999999999999933.199-E3999999999999933.189-E3999999999999933.179-E3999999999999933.169-E4999999999999933.159-E4999999999999933.149-E4999999999999933.139-E4999999999999933.129-E4999999999999933.119-E4999999999999933.109-E4999999999999933.198-E4999999999999933.188-E4999999999999933.178-E3999999999999933.168-E3999999999999933.158-E3999999999999933.148-E3999999999999933.138-E3999999999999933.128-E4999999999999933.118-E3999999999999933.108-E3999999999999933.197-E3999999999999933.187-E3999999999999933.177-E4999999999999933.167-E3999999999999933.157-E3999999999999933.147-E3999999999999933.137-E3999999999999933.127-E3999999999999933.117-E4999999999999933.107-E5999999999999933.196-E5999999999999933.186-E5999999999999933.176-E4999999999999933.166-E4999999999999933.156-E4999999999999933.146-E4999999999999933.136-E3999999999999933.126-E3999999999999933.116-E3999999999999933.106-E3999999999999933.195-E2999999999999933.185-E1999999999999933.175-E2999999999999933.165-E2999999999999933.155-E2999999999999933.145-E2999999999999933.135-E3999999999999933.125-E4999999999999933.115-E4999999999999933.105-E2999999999999933.194-E1999999999999933.184-E2999999999999933.174-E2999999999999933.164-E2999999999999933.154-E1999999999999933.144-E1999999999999933.134-E2999999999999933.124-E2999999999999933.114-E2999999999999933.104-E3999999999999933.193-E3999999999999933.183-E3999999999999933.173-E2999999999999933.163-E2999999999999933.153-E999999999999933.143-E2999999999999933.133-E2999999999999933.123-E2999999999999933.113-E3999999999999933.103-E3999999999999933.192-E3999999999999933.182-E3999999999999933.172-E3999999999999933.162-E4999999999999933.152-E4999999999999933.142-E5999999999999933.132-E6999999999999933.122-E7999999999999933.112-E6999999999999933.102-E6999999999999933.191-E7999999999999933.181-E8999999999999933.171-E8999999999999933.161-E8999999999999933.151-E9999999999999933.141-E8999999999999933.131-E8999999999999933.121-E43.111-E43.101-E43.19-E1000000000000043.18-E1000000000000043.17-E43.16-E43.15-E43.14-E43.143100.04310.0431.043.14000000000000004.30.4

This is not because of the complier. It is happening because you are doing
i /= 10; //slice end
So when you do 13.4 after the first run it wont give you 1.34 it will give you something like 1.339999999999999999 which is 1.34.
Check Retain precision with double in Java for more details.
If you just want to reverse the number you can do
private static String numToString(double i) {
String returnString = new StringBuilder(Double.toString(i)).reverse().toString();
return i>=0?returnString:"-"+returnString.substring(0,returnString.length()-1);
}

for (; i > 0; ) { //loop backwards through number
revNumber += "" + i % 10; //get the end
i /= 10; //slice end
}
This loop never finishes until it breaks at a much later time than it should. i % 10 doesn't cut off the end of a double. It works well with an int but not with a double. Hence the 134->13.4->1.34->.134-> etc.... So you get an argumentoutofrange exception or something similar to that. Else the compiler just keeps doing it for the max memory that a double can handle.

Related

Does Java have a limit on loop cycles?

I solved the Project Euler problem #14 https://projecteuler.net/problem=14 on Java, but when I run it in Powershell, it stops iterating at exactly i = 113383 every time. I rewrote the solution on python, and it works perfectly fine, albeit slowly. According to my (identical) python solution, the answer is that the number that produces the longest chain is 837799 and the chain is 524 operations long.
Why does the Java solution not finish the for-loop? Is there some kind of limit in Java on how long it can stay in a loop? I cannot come up with any other explanation. Java code below. I wrote the System.out.println(i) there just to see what is going on.
class ProjectEuler14 {
public static void main(String[] args) {
int largestNumber = 1;
int largestChain = 1;
int currentNumber;
int chainLength;
for (int i = 2; i < 1000000; i++) {
System.out.println(i);
currentNumber = i;
chainLength = 0;
while (currentNumber != 1) {
if (currentNumber % 2 == 0) currentNumber /= 2;
else currentNumber = 3 * currentNumber + 1;
chainLength++;
}
if (chainLength > largestChain) {
largestChain = chainLength;
largestNumber = i;
}
}
System.out.println("\n\nThe number under million that produces the "
+ "longest chain is " + largestNumber +
" and the chain's length is " + largestChain);
}
}
It's not the for loop. It's the while loop. The condition currentNumber != 1 is always true; forever.
In java, an int is specifically defined as an integral number between -2^31 and +2^31 -1, inclusive, and operations 'roll over'. try it!
int x = 2^31 -1;
x++;
System.out.println(x);
this prints a large negative number (in fact, precisely -2^31).
It's happening in your algorithm, and that's why it never finishes.
A trivial solution is to 'upgrade' to longs; they are just as fast, really (yay 64-bit processors!) and use 64 bits, thus giving them a range of -2^63 to +2^63-1.
Python sort of scales up its numbers into slowness silently, java makes different choices (and, for crypto and other purposes, that rollover thing is in fact desired).
If you want to go even further, you can always use BigInteger, which grows as much as you need forever (becoming slower and taking more memory as it goes).
To know rollover occurred, the 3* operation would then result in a number that is lower than the original, and you can check for that:
replace:
else currentNumber = 3 * currentNumber + 1;
with:
else {
int newNumber = currentNumber * 3 + 1;
if (newNumber < currentNumber) throw new IllegalStateException("Overflow has occurred; 3 * " + currentNumber + " + 1 exceeds ints capacities.");
currentNumber = newNumber;
}
and rerun it. You'll see your app nicely explain itself.
The currentNumber is exceeding size of int, use long instead.
Do you hava problem overflow int.
Change int to long.
long largestNumber = 1;
long largestChain = 1;
long currentNumber;
long chainLength;
for (int i = 2; i < 1000000; i++) {
//System.out.println(i);
currentNumber = i;
chainLength = 0;
while (currentNumber != 1) {
//System.out.println("# = " + currentNumber);
if (currentNumber % 2 == 0) {
currentNumber /= 2;
} else {
currentNumber = (3 * currentNumber) +1 ;
}
chainLength++;
}
// System.out.println("################################ " + i);
if (chainLength > largestChain) {
largestChain = chainLength;
largestNumber = i;
}
}
System.out.println("\n\nThe number under million that produces the "
+ "longest chain is " + largestNumber
+ " and the chain's length is " + largestChain);

How to make java method not return anything if result is not correct

Hi everyone, I'm making a java program that will display all perfect numbers in a given range. I have to do this by using method and this is my code:
public static void main(String[] args) {
for (int i = 1; i <= 1000; i++){
String result = isPerfect(i);
System.out.println(result);
}
}
public static String isPerfect(int num){
String result = "";
int sum = 0;
for (int i = 1; i < num; i++){
if ((num % i) == 0){
sum += i;
}
}
if (sum == num){
result = "Number " + num + " is a perfect number";
}else{
result = "Number " + num + " is not a perfect number";
}
return result;
}
I expect to get a list consisting only of perfect numbers which for range from 1 to 1000 are 6, 28 and 496.
For the actual result I get these numbers but I also get the line from else part in the method, that is "Number #num is not a perfect number". I tried changing the return method but I couldn't find a solution to this. I put an empty string when the result is not true but then I get my line for perfect number 6 and then everything till the next perfect number is empty line, in this case from 6 and 28 there are 22 empty lines. How can I change this so my method doesn't return anything if the result is not the one that I want?
pic of my result
So I'd like not to get anything from that pic except for "Number 496 is a perfect number"
You are really close, there is one thing that I would change and that's returning a boolean rather than a String. This way the method isPerfect will return either true or false, which is kind of logical as it's either a perfect number or its not.
And then from that point you can print the perfect numbers:
public static void main(String[] args) {
for (int i = 1; i <= 1000; i++){
if(isPerfect(i)){
System.out.println("Number "+ i + " is a perfect number");
}
}
}
public static boolean isPerfect(int num){
int sum = 0;
for (int i = 1; i < num; i++){
if ((num % i) == 0){
sum += i;
}
}
if (sum == num){
return true;
}
return false;
}
Just remove println, and in your if do this: "is a perfect number\n"
Then in your else, put empty string. So this if you want to stick to yuor code and dont want to change anything. If you want to modify your code a lot use #Fubars method which is also correct

Create my own BigInteger by using String in Java

I have to create a class MyBigInteger to calculate the operations: mod inverse and mod power with >very big integers ( about 60 digits in Decimals or more ). To solve this, I use String to store my >numbers and create some basic functions such as add, subtract, mod, div,... But the problem I got >here is that: while my add and subtract methods work right, my multiple functions only works with >small numbers, and if I use input with numbers 7, 8 or more digits, my program will not responds. I >think my idea to use String to store big numbers may be a bad idea and If i use array to store them, >will my class work more quickly, won't it?
Below is my code.The add and subtract method seem to work correctly so I will only post the method >multiple.
First is method a MyBigInteger multiply a integer. I use it to create my multipler between two >MyBigInteger:
public class MyBigInteger {
private String val;
public static final MyBigInteger ZERO = new MyBigInteger("0");
...
private MyBigInteger mutiple( int k){
MyBigInteger result = ZERO;
if( k == 0) return result;
for( int i = 1; i <= Math.abs(k); i++) result = result.add(this);
if( k > 0) return result;
else return result.getOpposite(); // result.add(result.getOpposite()) == ZERO
}
public MyBigInteger mutiple( MyBigInteger mbi){
MyBigInteger result = ZERO;
if( mbi.toString().charAt(0) != '-'){
for( int i = mbi.toString().length() - 1; i >= 0; i--){
result = result.add(this.mutiple(Integer.parseInt(mbi.toString().charAt(mbi.toString().length() - i -1) + "")).mutiple((int)Math.pow(10, i)));
}
} else{
for( int i = mbi.toString().length() - 1 ; i >= 1; i--){
result = result.add(this.mutiple(Integer.parseInt(mbi.toString().charAt(mbi.toString().length() - i) + "")).mutiple((int)Math.pow(10, i-1)));
}
result = result.getOpposite();
}
return result;
}
Many thanks for any help you may be able to provide
Sorry for this, but the Multiplication method was fixed and It works perfectly. But that it not the only problem in my Class. I created a mod method by using a subtraction method. And In my subtraction method, I use subAbs method which is a particular subtraction for two Positive MyBigNumber.
public MyBigInteger subAbs( MyBigInteger mBI){
String result = "";
int i = this.getLength();
int j = mBI.getLength();
int s = 0;
int r = 0;
String temp = "";
String val1 = this.toString();
String val2 = mBI.toString();
if( this.equalsTo(mBI) == true ) return ZERO;
else
if( this.greaterThan(mBI) == true){
for( int k = 0; k < i - j; k++) temp += "0";
val2 = temp + val2;
for( int k = i-1; k > 0; k-- ){
//And the statement right behind this comment is the wrong line (224) in the image
s = 10 + Integer.parseInt(val1.charAt(k) + "") - Integer.parseInt(val2.charAt(k) + "") - r;
if( s >= 10){
s = s - 10;
r = 0;
} else r = 1;
result = Integer.valueOf(s).toString() + result;
}
s = Integer.parseInt(val1.charAt(0) + "") - Integer.parseInt(val2.charAt(0)+"") - r;
if( s >= 0 ) result = s + result;
else result = Integer.valueOf(s).toString() + result;
return new MyBigInteger(result);
} else return new MyBigInteger("-" + mBI.subAbs(this).toString());
}
And if I put in a big number, I get a exception:
The problem may start from the method subAbs.
Your multiply method is simply adding over and over and over. This works fine for small numbers, but when you put in large numbers you are doing tons of calculations, the computer has to take a long time to figure it out.
How would you multiply 100x12345 by hand? Would you add 12345+12345, then take that and add 12345, then take that and add 12345, and repeat 100 times? That's what your alogirthm is doing now. You should try to implement your multiply algorithm in the same way you would multiply 100x12345.

Iterate through each digit in a number

I am trying to create a program that will tell if a number given to it is a "Happy Number" or not. Finding a happy number requires each digit in the number to be squared, and the result of each digit's square to be added together.
In Python, you could use something like this:
SQUARE[d] for d in str(n)
But I can't find how to iterate through each digit in a number in Java. As you can tell, I am new to it, and can't find an answer in the Java docs.
You can use a modulo 10 operation to get the rightmost number and then divide the number by 10 to get the next number.
long addSquaresOfDigits(int number) {
long result = 0;
int tmp = 0;
while(number > 0) {
tmp = number % 10;
result += tmp * tmp;
number /= 10;
}
return result;
}
You could also put it in a string and turn that into a char array and iterate through it doing something like Math.pow(charArray[i] - '0', 2.0);
Assuming the number is an integer to begin with:
int num = 56;
String strNum = "" + num;
int strLength = strNum.length();
int sum = 0;
for (int i = 0; i < strLength; ++i) {
int digit = Integer.parseInt(strNum.charAt(i));
sum += (digit * digit);
}
I wondered which method would be quickest to split up a positive number into its digits in Java, String vs modulo
public static ArrayList<Integer> splitViaString(long number) {
ArrayList<Integer> result = new ArrayList<>();
String s = Long.toString(number);
for (int i = 0; i < s.length(); i++) {
result.add(s.charAt(i) - '0');
}
return result; // MSD at start of list
}
vs
public static ArrayList<Integer> splitViaModulo(long number) {
ArrayList<Integer> result = new ArrayList<>();
while (number > 0) {
int digit = (int) (number % 10);
result.add(digit);
number /= 10;
}
return result; // LSD at start of list
}
Testing each method by passing Long.MAX_VALUE 10,000,000 times, the string version took 2.090 seconds and the modulo version 2.334 seconds. (Oracle Java 8 on 64bit Ubuntu running in Eclipse Neon)
So not a lot in it really, but I was a bit surprised that String was faster
In the above example we can use:
int digit = Character.getNumericValue(strNum.charAt(i));
instead of
int digit = Integer.parseInt(strNum.charAt(i));
You can turn the integer into a string and iterate through each char in the string. As you do that turn that char into an integer
This code returns the first number (after 1) that fits your description.
public static void main(String[] args) {
int i=2;
// starting the search at 2, since 1 is also a happy number
while(true) {
int sum=0;
for(char ch:(i+"").toCharArray()) { // casting to string and looping through the characters.
int j=Character.getNumericValue(ch);
// getting the numeric value of the current char.
sum+=Math.pow(j, j);
// adding the current digit raised to the power of itself to the sum.
}
if(sum==i) {
// if the sum is equal to the initial number
// we have found a number that fits and exit.
System.out.println("found: "+i);
break;
}
// otherwise we keep on searching
i++;
}
}

Counting trailing zeros of numbers resulted from factorial

I'm trying to count trailing zeros of numbers that are resulted from factorials (meaning that the numbers get quite large). Following code takes a number, compute the factorial of the number, and count the trailing zeros. However, when the number is about as large as 25!, numZeros don't work.
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
double fact;
int answer;
try {
int number = Integer.parseInt(br.readLine());
fact = factorial(number);
answer = numZeros(fact);
}
catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static double factorial (int num) {
double total = 1;
for (int i = 1; i <= num; i++) {
total *= i;
}
return total;
}
public static int numZeros (double num) {
int count = 0;
int last = 0;
while (last == 0) {
last = (int) (num % 10);
num = num / 10;
count++;
}
return count-1;
}
I am not worrying about the efficiency of this code, and I know that there are multiple ways to make the efficiency of this code BETTER. What I'm trying to figure out is why the counting trailing zeros of numbers that are greater than 25! is not working.
Any ideas?
Your task is not to compute the factorial but the number of zeroes. A good solution uses the formula from http://en.wikipedia.org/wiki/Trailing_zeros (which you can try to prove)
def zeroes(n):
i = 1
result = 0
while n >= i:
i *= 5
result += n/i # (taking floor, just like Python or Java does)
return result
Hope you can translate this to Java. This simply computes [n / 5] + [n / 25] + [n / 125] + [n / 625] + ... and stops when the divisor gets larger than n.
DON'T use BigIntegers. This is a bozosort. Such solutions require seconds of time for large numbers.
You only really need to know how many 2s and 5s there are in the product. If you're counting trailing zeroes, then you're actually counting "How many times does ten divide this number?". if you represent n! as q*(2^a)*(5^b) where q is not divisible by 2 or 5. Then just taking the minimum of a and b in the second expression will give you how many times 10 divides the number. Actually doing the multiplication is overkill.
Edit: Counting the twos is also overkill, so you only really need the fives.
And for some python, I think this should work:
def countFives(n):
fives = 0
m = 5
while m <= n:
fives = fives + (n/m)
m = m*5
return fives
The double type has limited precision, so if the numbers you are working with get too big the double will be only an approximation. To work around this you can use something like BigInteger to make it work for arbitrarily large integers.
You can use a DecimalFormat to format big numbers. If you format your number this way you get the number in scientific notation then every number will be like 1.4567E7 this will make your work much easier. Because the number after the E - the number of characters behind the . are the number of trailing zeros I think.
I don't know if this is the exact pattern needed. You can see how to form the patterns here
DecimalFormat formater = new DecimalFormat("0.###E0");
My 2 cents: avoid to work with double since they are error-prone. A better datatype in this case is BigInteger, and here there is a small method that will help you:
public class CountTrailingZeroes {
public int countTrailingZeroes(double number) {
return countTrailingZeroes(String.format("%.0f", number));
}
public int countTrailingZeroes(String number) {
int c = 0;
int i = number.length() - 1;
while (number.charAt(i) == '0') {
i--;
c++;
}
return c;
}
#Test
public void $128() {
assertEquals(0, countTrailingZeroes("128"));
}
#Test
public void $120() {
assertEquals(1, countTrailingZeroes("120"));
}
#Test
public void $1200() {
assertEquals(2, countTrailingZeroes("1200"));
}
#Test
public void $12000() {
assertEquals(3, countTrailingZeroes("12000"));
}
#Test
public void $120000() {
assertEquals(4, countTrailingZeroes("120000"));
}
#Test
public void $102350000() {
assertEquals(4, countTrailingZeroes("102350000"));
}
#Test
public void $1023500000() {
assertEquals(5, countTrailingZeroes(1023500000.0));
}
}
This is how I made it, but with bigger > 25 factorial the long capacity is not enough and should be used the class Biginteger, with witch I am not familiar yet:)
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.print("Please enter a number : ");
long number = in.nextLong();
long numFactorial = 1;
for(long i = 1; i <= number; i++) {
numFactorial *= i;
}
long result = 0;
int divider = 5;
for( divider =5; (numFactorial % divider) == 0; divider*=5) {
result += 1;
}
System.out.println("Factorial of n is: " + numFactorial);
System.out.println("The number contains " + result + " zeroes at its end.");
in.close();
}
}
The best with logarithmic time complexity is the following:
public int trailingZeroes(int n) {
if (n < 0)
return -1;
int count = 0;
for (long i = 5; n / i >= 1; i *= 5) {
count += n / i;
}
return count;
}
shamelessly copied from http://www.programcreek.com/2014/04/leetcode-factorial-trailing-zeroes-java/
I had the same issue to solve in Javascript, and I solved it like:
var number = 1000010000;
var str = (number + '').split(''); //convert to string
var i = str.length - 1; // start from the right side of the array
var count = 0; //var where to leave result
for (;i>0 && str[i] === '0';i--){
count++;
}
console.log(count) // console shows 4
This solution gives you the number of trailing zeros.
var number = 1000010000;
var str = (number + '').split(''); //convert to string
var i = str.length - 1; // start from the right side of the array
var count = 0; //var where to leave result
for (;i>0 && str[i] === '0';i--){
count++;
}
console.log(count)
Java's doubles max out at a bit over 9 * 10 ^ 18 where as 25! is 1.5 * 10 ^ 25. If you want to be able to have factorials that high you might want to use BigInteger (similar to BigDecimal but doesn't do decimals).
I wrote this up real quick, I think it solves your problem accurately. I used the BigInteger class to avoid that cast from double to integer, which could be causing you problems. I tested it on several large numbers over 25, such as 101, which accurately returned 24 zeros.
The idea behind the method is that if you take 25! then the first calculation is 25 * 24 = 600, so you can knock two zeros off immediately and then do 6 * 23 = 138. So it calculates the factorial removing zeros as it goes.
public static int count(int number) {
final BigInteger zero = new BigInteger("0");
final BigInteger ten = new BigInteger("10");
int zeroCount = 0;
BigInteger mult = new BigInteger("1");
while (number > 0) {
mult = mult.multiply(new BigInteger(Integer.toString(number)));
while (mult.mod(ten).compareTo(zero) == 0){
mult = mult.divide(ten);
zeroCount += 1;
}
number -= 1;
}
return zeroCount;
}
Since you said you don't care about run time at all (not that my first was particularly efficient, just slightly more so) this one just does the factorial and then counts the zeros, so it's cenceptually simpler:
public static BigInteger factorial(int number) {
BigInteger ans = new BigInteger("1");
while (number > 0) {
ans = ans.multiply(new BigInteger(Integer.toString(number)));
number -= 1;
}
return ans;
}
public static int countZeros(int number) {
final BigInteger zero = new BigInteger("0");
final BigInteger ten = new BigInteger("10");
BigInteger fact = factorial(number);
int zeroCount = 0;
while (fact.mod(ten).compareTo(zero) == 0){
fact = fact.divide(ten);
zeroCount += 1;
}
}

Categories