I'm doing a project and i have a really simple hash function in java that SHOULD read each "data" (which is a generic type that is a String or Double type read by file) character and make a sum of their values that will be used as hashcode.
I thought that i could convert each character to Hexadecimal, and then "decode" or "parseInt" the obtained String, but it does not work and i do not understand why.
Here is my method:
public long HashFunction(T data){
String bytes = data.toString();
int value=0;
for (int i=0; i<bytes.length(); i++)
value = value + Integer.decode(Integer.toHexString( bytes.charAt(i) | 0x100000).substring(1));
return (value%1583)%(size);
//1583 prime number not near to the power of 2, size is the size of the array of my hashtable
}
And here is my error, 0038 should be an "8":
Exception in thread "main" java.lang.NumberFormatException: For input string: "0038"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.valueOf(Unknown Source)
at java.lang.Integer.decode(Unknown Source)
at dizionario_package.HashTable.HashFunction(HashTable.java:22)
at dizionario_package.HashTable.HashInsert(HashTable.java:29)
at dizionario_package.RecordReader.CreateHTFromFile(RecordReader.java:24)
at dizionario_package.proviamo.main(proviamo.java:8)
Also, i'm sure that the error is in this function, because if i use the java hashcode method, it works.
Thanks in advance.
You need to tell decode you're using hex. Prefix the string with 0x.
value = Integer.decode("0x"+"10038".substring(1));
Related
I tried to convert Hex to BigInteger, here is source code:
public static void main (String[] args)
{
BigInteger a = new BigInteger("c6e87a3b3ef791287ac85a0c7836dd8305dd9a4c0024123db9145bb5067a8abf142e9001b0788039fd4d676b59db2110da23532282c7648d94fdbf29b731b0d21f9ca51acd44063f271326915283af97f0822519bbe2a6b80618e45e6194b2445d5afe70cf2c10569034966f3bc3b9a30d3ac4f06dbbca89fce7ef64ee14de3dL", 16);
BigInteger b = new BigInteger("9e5d1bd4f53eebc8a695c61ba4436e38af273fd6733115611fded8dd407b5f0bc04301829dc6ed921af866c3c7977839fc75831152307f8e50e3c0f9107b6ae82ddab584807ea5ba7f32f9bfcab6218c6c6367817dfdd3b2ccc5c21cc9550b9248cac34dfb0d22151c196ca843f15614b3f6b044f9c5e727dc0b44f441c2ed7fL", 16);
System.out.println(a);
System.out.println(b);
// System.out.println(modInv(a, b));
}
I tried to run this source code, but I got Runtime error like this:
Exception in thread "main" java.lang.NumberFormatException: For input
string: "....14de3dL" at
java.lang.NumberFormatException.forInputString(Unknown Source) at
java.lang.Integer.parseInt(Unknown Source) at
java.math.BigInteger.(Unknown Source) at
sss.main.main(main.java:15)
Is there something problem in source code? I can't find it.
As pointed out in comment L is not part of Hexadecimal presentation.L is used to represent the string as Long, so it is an invalid character in the hexadecimal presentation. Code below should be helpful
BigInteger a = new BigInteger("c6e87a3b3ef791287ac85a0c7836dd8305dd9a4c0024123db9145bb5067a8abf142e9001b0788039fd4d676b59db2110da23532282c7648d94fdbf29b731b0d21f9ca51acd44063f271326915283af97f0822519bbe2a6b80618e45e6194b2445d5afe70cf2c10569034966f3bc3b9a30d3ac4f06dbbca89fce7ef64ee14de3d", 16);
System.out.println(a.toString());
First of All, L is not included in Hex Numbers that you wrote in the end of both strings. you can visit this link for help on Hex Numbers
https://en.wikipedia.org/wiki/Hexadecimal
After visiting this , please view this post as well
Java convert a HEX String to a BigInt
I am trying to parse a string safely,
public <T> long safeParseLong(T s){
try {
return Long.parseLong(s.toString());
}catch (NumberFormatException e){
return 0;
}
}
This will always work and if the string is not parsable, it will return 0.
However, is there a way to know what the reason is for it to be unparsable? Specifically, I want to know if it is not a number at all ("foo") or the number is too large (≥ 9223372036854775808).
The Long.parseLong method will throw a NumberFormatException if the string isn't a number or if the number wouldn't fit in a long.
If the exception is thrown, then test whether the string fits the regular expression for a number, "[+-]?[0-9]+". If it matches, it's a number that couldn't fit in a long. If it doesn't match, then it wasn't a number at all, e.g. "foo".
boolean isNumber = s.toString().matches("[+-]?[0-9]+");
But you are returning 0 if there was an error. This is indistinguishable from if the content of the string were "0". Perhaps it would be better to let an exception be thrown from this method. But instead of a NumberFormatException, you could create and throw a NotANumberException if it's not a numeric string, or a NumberMagnitudeTooLargeException if the parsing failed because it's too large to fit in a long.
Unfortunately, Long.parseLong will throw NumberFormatException in any case.
Long.parseLong(new String(new BigInteger(Long.toString(Long.MAX_VALUE)).add(new BigInteger("1")).toString()));
results in:
Exception in thread "main" java.lang.NumberFormatException: For input string: "9223372036854775808"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at Main.main(Main.java:13)
So, in Java I have a large number in the command argument, let's say 12345678910, and I cannot use bigInteger, and I already did:
String[] g = args[1].split("");
So, my string is put in a string array. But, I cannot use:
int[] ginormintOne = new int[g.length];
for(int n = 0; n < g.length; n++) {
ginormintOne[n] = Integer.parseInt(g[n]);
}
It gives me this:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Ginormint.main(Ginormint.java:67)
I think my numbers are too large for int. Any idea on how to convert it to a large number array?
You are splitting on an empty string. For example,
"123 456".split("")
results in this array:
["" "1" "2" "3" " " "4" "5" "6"]
This is where your exception comes from.
The first element of the array from args[1].split("") is an empty string that to my opinion causes the exception java.lang.NumberFormatException since it cannot be converted to an Integer
Use Long.parseLong instead of Integer.parseInt and a long[] instead of Long.parseLong.
But that said, the NumberFormatException indicates the failure is because you're passing it an empty string. Are you sure you're splitting the string correctly, or that splitting is even necessary? The args array in main is already split on spaces, assuming that's where args is coming from.
I am getting an error because of the following line of code:
int x = color(Integer.parseInt("ffffffde",16));
I think it might be because it is a minus value
Any ideas why or how or how to fix it?
EDIT:
Sorry, didn't include the actual error. here it is:
Exception in
thread "Animation Thread" java.lang.NumberFormatException: For input
string: "ffffffde" at
java.lang.NumberFormatException.forInputString(Unknown Source) at
java.lang.Integer.parseInt(Unknown Source)
EDIT 2:
The value ("ffffffde") is being created by the following code:
Integer.toHexString(int_val);
EDIT 3:
Turns out it is a known bug (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4215269)
Although you can convert integers to hex strings, you cannot convert them back if they are negative numbers!!
ffffffde is bigger than integer max value
Java int is 32 bit signed type ranges from –2,147,483,648 to 2,147,483,647.
ffffffde = 4,294,967,262
Edit
You used Integer.toHexString(int_val) to turn a int into a hex string. From the doc of that method:
Returns a string representation of the integer argument as an unsigned integer in base 16.
But int is a signed type.
USE
int value = new BigInteger("ffffffde", 16).intValue();
to get it back as a negative value.
If you are getting error like this,
Exception in thread "main" java.lang.NumberFormatException: For input string: "ffffffde"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:461)
at com.TestStatic.main(TestStatic.java:22)
Then there is problem with value you are passing that is ffffffde . This is not a valid hex value for parsing to int.
Please try this
int x = Integer.parseInt("ffffde",16);
System.out.println(x);
It should work.
For hex values more than that you have to pars to Long
Long x = Long.parseLong("ffffffde",16);
System.out.println(x);
And this also should work
i searched, i found, but it all didn't work. my problem is that the NumberFormatException is thrown while I want to cast from String to double.
The string array atomized contains many strings and I tried to make an output before to make them visible so I could be sure there is data. the only problem is the double value. it is something like 5837848.3748980 but the valueOf method always throws the exception here. I have no idea why.
try
{
int key = Integer.valueOf(atomized[0]);
double value = Double.valueOf(atomized[1].trim());
int role = Integer.valueOf(atomized[2]);
Double newAccountState = this.bankKonto.charge(key, value, role);
System.out.println("NEW Account State "+newAccountState);
this.answerClient(newAccountState.toString());
}
catch (NumberFormatException e)
{
System.out.println(e.getClass().toString()+" "+e.getMessage());
}
Exception output:
java.lang.NumberFormatException: For input string: "109037.0"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.valueOf(Unknown Source)
at vsys.ue02.server.Bank.computeData(Bank.java:122)
at vsys.ue02.server.Bank.run(Bank.java:160)
It works fine here. So I'd assume your system locale has , rather than . for decimal separator. To avoid these things you can use DecimalFormat:
new DecimalFormat().parse("5837848.3748980");
Judging by the name of your variable - account - I assume you are dealing with money. You must never use floating point types to represent money. Use BigDecimal, or possibly int
This is a starting point for using DecimalFormat to convert strings to numbers. Also, if you are dealing with money and currencies, you should consider using BigDecimal instead of double.
You are using Integer.parseInt on a number with a decimal point - that is not a valid integer - visible in your stack trace