There are many ways of converting a String to an Integer object. Which is the most efficient among the below:
Integer.valueOf()
Integer.parseInt()
org.apache.commons.beanutils.converters.IntegerConverter
My usecase needs to create wrapper Integer objects...meaning no primitive int...and the converted data is used for read-only.
If efficiency is your concern, then creating an Integer object is much more expensive than parsing it. If you have to create an Integer object, I wouldn't worry too much about how it is parsed.
Note: Java 6u14 allows you to increase the size of your Integer pool with a command line option -Djava.lang.Integer.IntegerCache.high=1024 for example.
Note 2: If you are reading raw data e.g. bytes from a file or network, the conversion of these bytes to a String is relatively expensive as well. If you are going to write a custom parser I suggest bypassing the step of conversing to a string and parse the raw source data.
Note 3: If you are creating an Integer so you can put it in a collection, you can avoid this by using GNU Trove (trove4j) which allows you to store primitives in collections, allowing you to drop the Integer creation as well.
Ideally, for best performance you want to avoid creating any objects at all.
Your best bet is to use Integer.parseInt. This will return an int, but this can be auto-boxed to an Integer. This is slightly faster than valueOf, as when your numbers are between -128 and 127 it will use the Integer cache and not create new objects. The slowest is the Apache method.
private String data = "99";
public void testParseInt() throws Exception {
long start = System.currentTimeMillis();
long count = 0;
for (int i = 0; i < 100000000; i++) {
Integer o = Integer.parseInt(data);
count += o.hashCode();
}
long diff = System.currentTimeMillis() - start;
System.out.println("parseInt completed in " + diff + "ms");
assert 9900000000L == count;
}
public void testValueOf() throws Exception {
long start = System.currentTimeMillis();
long count = 0;
for (int i = 0; i < 100000000; i++) {
Integer o = Integer.valueOf(data);
count += o.hashCode();
}
long diff = System.currentTimeMillis() - start;
System.out.println("valueOf completed in " + diff + "ms");
assert 9900000000L == count;
}
public void testIntegerConverter() throws Exception {
long start = System.currentTimeMillis();
IntegerConverter c = new IntegerConverter();
long count = 0;
for (int i = 0; i < 100000000; i++) {
Integer o = (Integer) c.convert(Integer.class, data);
count += o.hashCode();
}
long diff = System.currentTimeMillis() - start;
System.out.println("IntegerConverter completed in " + diff + "ms");
assert 9900000000L == count;
}
parseInt completed in 5906ms
valueOf completed in 7047ms
IntegerConverter completed in 7906ms
I'm always amazed how quickly many here dismiss some investigation into performance problems. Parsing a int for base 10 is a very common task in many programs. Making this faster could have a noticable positive effect in many environments.
As parsing and int is actually a rather trivial task, I tried to implement a more direct approach than the one used in the JDK implementation that has variable base. It turned out to be more than twice as fast and should otherwise behave exactly the same as Integer.parseInt().
public static int intValueOf( String str )
{
int ival = 0, idx = 0, end;
boolean sign = false;
char ch;
if( str == null || ( end = str.length() ) == 0 ||
( ( ch = str.charAt( 0 ) ) < '0' || ch > '9' )
&& ( !( sign = ch == '-' ) || ++idx == end || ( ( ch = str.charAt( idx ) ) < '0' || ch > '9' ) ) )
throw new NumberFormatException( str );
for(;; ival *= 10 )
{
ival += '0'- ch;
if( ++idx == end )
return sign ? ival : -ival;
if( ( ch = str.charAt( idx ) ) < '0' || ch > '9' )
throw new NumberFormatException( str );
}
}
To get an Integer object of it, either use autoboxing or explicit
Interger.valueOf( intValueOf( str ) ).
I know this isn't amongst your options above. IntegerConverter is ok, but you need to create an instance of it. Take a look at NumberUtils in Commons Lang:
Commons Lang NumberUtils
this provides the method toInt:
static int toInt(java.lang.String str, int defaultValue)
which allows you to specify a default value in the case of a failure.
NumberUtils.toInt("1", 0) = 1
That's the best solution I've found so far.
Here's a good article comparing the performance of different methods of parsing integers
And here's the code used, with overflow/underflow checks.
public static int parseInt( final String s )
{
if ( string == null )
throw new NumberFormatException( "Null string" );
// Check for a sign.
int num = 0;
int sign = -1;
final int len = s.length( );
final char ch = s.charAt( 0 );
if ( ch == '-' )
{
if ( len == 1 )
throw new NumberFormatException( "Missing digits: " + s );
sign = 1;
}
else
{
final int d = ch - '0';
if ( d < 0 || d > 9 )
throw new NumberFormatException( "Malformed: " + s );
num = -d;
}
// Build the number.
final int max = (sign == -1) ?
-Integer.MAX_VALUE : Integer.MIN_VALUE;
final int multmax = max / 10;
int i = 1;
while ( i < len )
{
int d = s.charAt(i++) - '0';
if ( d < 0 || d > 9 )
throw new NumberFormatException( "Malformed: " + s );
if ( num < multmax )
throw new NumberFormatException( "Over/underflow: " + s );
num *= 10;
if ( num < (max+d) )
throw new NumberFormatException( "Over/underflow: " + s );
num -= d;
}
return sign * num;
}
And even faster implementation, without overflow/underflow checks.
public static int parseInt( final String s )
{
// Check for a sign.
int num = 0;
int sign = -1;
final int len = s.length( );
final char ch = s.charAt( 0 );
if ( ch == '-' )
sign = 1;
else
num = '0' - ch;
// Build the number.
int i = 1;
while ( i < len )
num = num*10 + '0' - s.charAt( i++ );
return sign * num;
}
Don't even waste time thinking about it. Just pick one that seems to fit with the rest of the code (do other conversions use the .parse__() or .valueOf() method? use that to be consistent).
Trying to decide which is "best" detracts your focus from solving the business problem or implementing the feature.
Don't bog yourself down with trivial details. :-)
On a side note, if your "use case" is specifying java object data types for your code - your BA needs to step back out of your domain. BA's need to define "the business problem", and how the user would like to interact with the application when addressing the problem.
Developers determine how best to build that feature into the application with code - including the proper data types / objects to handle the data.
If efficiency is your concern, use int: it is much faster than Integer.
Otherwise, class Integer offers you at least a couple clear, clean ways:
Integer myInteger = new Integer(someString);
Integer anotherInteger = Integer.valueOf(someOtherString);
I tried a comparison of valueOf, parseInt, Ints.tryParse, NumberUtils.createInteger and NumberUtils.toInt with the program below. I was on jdk 1.8.0
As expected, the methods that did not need to create an Integer object were the fastest. My results were:
valueOf took: 77
parseInt took: 61
Ints.tryParse took: 117
numberUtils.createInteger took: 169
numberUtils.toInt took: 63
So the summary is:
If you can get by using an int, use Integer.parseInt.
If you absolutely need an Integer, use Integer.valueOf
If you need the convenience of not handling exceptions when you parse, or if you are unsure of the format of the input (i.e its a string that need not be a number) use Ints.tryParse
The code I used was:
public class HelloWorld {
public static int limit = 1000000;
public static String sint = "9999";
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
Integer integer = Integer.valueOf(sint);
}
long end = System.currentTimeMillis();
System.out.println("valueOf took: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
int integer = Integer.parseInt(sint);
}
end = System.currentTimeMillis();
System.out.println("parseInt took: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
int integer = Ints.tryParse(sint);
}
end = System.currentTimeMillis();
System.out.println("Ints.tryParse took: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
Integer integer = NumberUtils.createInteger(sint);
}
end = System.currentTimeMillis();
System.out.println("numberUtils.createInteger took: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
int integer = NumberUtils.toInt(sint);
}
end = System.currentTimeMillis();
System.out.println("numberUtils.toInt took: " + (end - start));
}
}
ParseInt returns an int, not a java.lang.Integer, so if you use tat method you would have to do
new Integer (Integer.parseInt(number));
I´ve heard many times that calling Integer.valueOf() instead of new Integer() is better for memory reasons (this coming for pmd)
In JDK 1.5, calling new Integer()
causes memory allocation.
Integer.valueOf() is more memory
friendly.
http://pmd.sourceforge.net/rules/migrating.html
In addition to that, Integer.valueOf allows caching, since values -127 to 128 are guaranteed to have cached instances. (since java 1.5)
Herro - kinda new to Java so forgive my ignorance.
I was searching for a a way to parse a mixed string (letters & numbers) into an INT (kinda like javascript does). Couldn't find anything in the JAVADOC files so after much searching i just wrote a function that does it:
// This function takes a string mixed with numbers and letters and returns an INT with
// the first occurrence of a number (INT) in said string, ignoring the rest;
// -- Basically, loop checks if char is a digit, if yes, puts digit back into new array, if no, puts a whitespace in its place
// this creates an array with only digits; By converting it to a string and then trimming whitespaces, it gets parsed into an INT
public static int mixedStringToInt (String str) {
boolean flag = true;
boolean isNumber = false;
final String refNumbers = "0123456789";
int strlen = str.length();
char[] numberArray = new char[strlen];
char[] stringArray = str.toCharArray();
for (int i = 0; i < strlen;i++){
if(refNumbers.indexOf(stringArray[i]) > 0 && flag){
// if current char is a digit
isNumber = true;
while (flag){
numberArray[i] = stringArray[i];
if(i+1 >= strlen || refNumbers.indexOf(stringArray[i+1]) < 0) flag = false;
i++;
}
} else {
// if current char is not a digit
numberArray[i] = ' ';
}
}
if (isNumber){
return Integer.valueOf(new String(numberArray).trim());
} else return 0;
}
Is this useful for anyone besides me? Did i waste my time writing this as there is already a method that does what i wanted to do?
Another way is this method:
public class stringtoInteger {
private static int stringtoInteger(String x) {
String value = "";
for (int i = 0; i < x.length(); i++) {
char character = x.charAt(i);
if (Character.isDigit(character)) {
value = value + character;
}
}
return Integer.parseInt(value);
}
}
Hope it helps!
Related
This question already has answers here:
Reverse a string in Java
(36 answers)
how to reverse an inputted number [duplicate]
(3 answers)
Closed 2 years ago.
What's the fastest way to reverse a Long value?
For example, 9876543210 should return 0123456789.
This is what I have right now:
long n = 0, c = 987654321 * 10; // *10 is to get 9876543210 as long value;
while (c > 0) n = n * 10 + c % 10;
System.out.println(n);
Your program encounters an infinite loop because you never change the value of c. Add c /= 10 at the end of each iteration and it will work, albeit the leading zero will be dropped due to it being a number.
long n = 0, c = 9876543210L;
while (c > 0){
n = n * 10 + c % 10;
c /= 10;
}
System.out.println(n);
If you need to have the leading zero, you should consider using Strings instead.
long c = 9876543210L;
final StringBuilder sb = new StringBuilder();
while (c > 0){
sb.append(c % 10);
c /= 10;
}
System.out.println(sb.toString());
I think this can be fast
long x = 1234567890L;
String reversed = new StringBuilder(Long.toString(x)).reverse().toString();
// reversed = "0987654321"
If You want to convert a reversed value to a long again:
long x = -1234567890000L;
StringBuilder reversed = new StringBuilder(Long.toString(x)).reverse();
System.out.println(reversed); // 0000987654321-
if (reversed.charAt(reversed.length() - 1) == '-') //remove `-` at last position
{
reversed.setLength(reversed.length() - 1);
}
while (reversed.charAt(0) == '0') //remove all `0` at the beginning
{
reversed.replace(0, 1, "");
}
System.out.println(reversed); // 987654321
long newLong = Long.parseLong(reversed.toString());
You can simply convert to string and then revert the String, in particular if you want string output in the end anyway. This should be quite straight forward and it has the leading 0, it might also be faster than doing calculations for each positions (but the cost of conversion in valueOf might cancel that advantage):
long c = 9876543210L;
String cAsString = String.valueOf(c);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
System.out.println(builder.toString());
or as a one liner
long c = 9876543210L;
String reverted = new StringBuilder(String.valueOf(c)).reverse().toString();
System.out.println(reverted);
I did a little comparison between the options of the current answers:
public static void main(String[] args) {
Instant start = Instant.now();
for (long i = 0; i < 100_000_000; i++) {
stringbuilderWithDirectCalcs(i);
}
Duration duration = Duration.between(start, Instant.now());
System.out.println("Took " + duration);
}
protected static void stringbuilderWithDirectCalcs(long value) {
final StringBuilder sb = new StringBuilder();
while (value > 0) {
sb.append(value % 10);
value /= 10;
}
// System.out.println(sb.toString());
}
protected static void stringbuilderConvenient(long value) {
String reverted = new StringBuilder(String.valueOf(value)).reverse().toString();
//System.out.println(reverted);
}
protected static void stringbuilderHandCrafted(long value) {
String cAsString = String.valueOf(value);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
//System.out.println(builder.toString());
}
I did three runs each. The outcome:
stringbuilderConvenient
Took PT6.988S / Took PT6.8S / Took PT6.68S
stringbuilderWithDirectCalcs:
Took PT6.17S / Took PT6.776S / Took PT6.692S
stringbuilderHandCrafted
Took PT18.205S / Took PT16.035S / Took PT17.025S
So, scanning the String by hand and sticking the StringBuilder together step by step seems out of the question. Obviously Stephen C was right in his comment that the calculations happen anyway when converting to String. But the approach based on Stringbuilder.reverse and handcalculating each position are pretty close (and any difference might be due to minor runtime fluctuations). So, one might choose the StringBuilder.reverse method over calculating each position by hand for readability with about the same performance.
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.
I have a serious problem. I need to get a number say
123454466666666666666665454545454454544598989899545455454222222222222222
and give the total of that number. I was trying for a long time. I couldn't get the answer. The problem is I didn't know which data type to use. I have tried it long. It accepts only 18 digits. I have gone through BigInteger. But I couldn't make arithmetic operations with it. so help me out with this problem..
1.Get it as a string
2.get length of it.
3.Loop through each character of it.
4.check if the character is a number.
5.If yes parse it to int.
6.Add all numbers together in the loop
OR
Use BigDecimal
You can get the result from the below code.
String string = "123454466666666666666665454545454454544598989899545455454222222222222222";
int count = 0;
for (int i = 0; i < string.length(); i++) {
count += Integer.parseInt(String.valueOf(string.charAt(i)));
}
System.out.println(count);
Just use it as a String. That's the easiest way to go for the task at hand.
public class Test022 {
public static void main(String[] args) {
String s = "123454466666666666666665454545454454544598989899545455454222222222222222";
int sum = 0;
for (int i=0; i<s.length(); i++){
sum += s.charAt(i) - '0';
}
System.out.println(sum);
}
}
i can suggest using this code and the numbers as String
/**
* Adds two non-negative integers represented as string of digits.
*
* #exception NumberFormatException if either argument contains anything other
* than base-10 digits.
*/
public static String add(String addend1, String addend2) {
StringBuilder buf = new StringBuilder();
for ( int i1 = addend1.length() - 1, i2 = addend2.length() - 1, carry = 0;
(i1 >= 0 && i2 >= 0) || carry != 0;
i1--, i2-- ) {
int digit1 = i1 < 0 ? 0 :
Integer.parseInt(Character.toString(addend1.charAt(i1)));
int digit2 = i2 < 0 ? 0 :
Integer.parseInt(Character.toString(addend2.charAt(i2)));
int digit = digit1 + digit2 + carry;
if (digit > 9) {
carry = 1;
digit -= 10;
} else {
carry = 0;
}
buf.append(digit);
}
return buf.reverse().toString();
}
BigInteger does support methods like add/multiply etc. See this for details.
BigInteger operand1 = new BigInteger("123454466666666666666665454545454454544598989899545455454222222222222222");
BigInteger operand2 = new BigInteger("123454466666666666666665454545454454544598989899545455454222222222222222");
System.out.println(operand1.add(operand2));
System.out.println(operand1.subtract(operand2));
System.out.println(operand1.multiply(operand2));
System.out.println(operand1.divide(operand2));
Here's a fun task...
Given a lot of version strings - assuming they are more or less semantic version semantic version numbers like 1.2.3 - what's a way to convert that to a long (in Java), so that it holds that "1.2.34" is less than "12.3.0"?
Here's what I have so far
public static Long toLong(String version) {
if (version == null || version.isEmpty()) {
return 0L;
}
String[] parts = version.split("[^0-9]");
long number = 0L;
long factor = 1;
for (int b = parts.length - 1; b >= 0; b--) {
try {
Long l = Long.parseLong(parts[b]);
number += l * factor;
factor = factor * 100;
} catch (NumberFormatException e){
// silently ignored
}
}
return number;
}
It assumes no position in the string has more than two digits (so 1.2.3.4567) will not work properly, but I can live with that. But I'd like to have something faster.
You can perform a similar transformation within String:
// add "." to format the major version
("." + versionString).
// replace each "." with "a00"
replaceAll("\\.", "a00").
// keep 2 digits, remove "a" and extra leading "0"
replaceAll("a0+([0-9]{2})", "$1");
This method can be easily adopted for different number of significant digits and/or different formats of the input string. Performance is ~2.4x slower than that of your toLong method (2.5 s to format 1M version strings). If performance is more important than simplicity of code, this is about 5.5x faster (0.2 s for 1M strings), than your toLong method:
public static Long toLong2(String versionString)
{
if (versionString == null || versionString.isEmpty() )
{
return 0L;
} // end if empty
char[] C = versionString.toCharArray();
int i, i1 = 0, i2 = C.length;
Long l, number = 0L, factor = 1L;
try
{
for (i = C.length - 1; i > 0; i--)
{
if (C[i] == '.')
{
i1 = i + 1;
l = Long.parseLong(versionString.substring(i1, i2) );
i2 = i;
number += l * factor;
factor = factor * 100L;
} // end if '.'
} // end for i
l = Long.parseLong(versionString.substring(0, i2) );
number += l * factor;
}
catch (NumberFormatException e)
{
// silently ignored
} // end try
return number;
} // end method toLong2
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.