charAt() and Math.pow() - java

Background:
I am making a simple base converter for a class assignment. I am fairly close to completion but need to tidy up the conversion algorithm to convert the user inputted value (in a given base) to a base 10 value.
Attempt:
import java.util.Scanner;
public class BaseConverter {
public static void main(String[] args) {
String numIn, intro1, prompt1, prompt2, output1;
int baseIn;
double numOut;
boolean flag = true;
Scanner kb = new Scanner(System.in);
intro1 = "This program converts values in different number bases to a decimal value.";
prompt1 = "Type in a number base (2 - 9): ";
while (flag == true){
System.out.println(intro1);
System.out.println(prompt1);
baseIn = kb.nextInt();
//Checking base value for outliers outside given range
if (baseIn < 2 || baseIn > 9) {
System.out.println("Base must be between 2 and 9");
System.exit(1);
}
prompt2 = "Type in a base "+baseIn+" number: ";
System.out.println(prompt2);
numIn = kb.next();
// System.out.println(numStore);
int counter = 0;
// Let's pretend baseIn is 3 and i starts at 3
for (int i = numIn.length(); i >= 1; i--){
numOut = (numIn.charAt(i-1) * Math.pow(baseIn, counter++));
System.out.println(numOut);
}
}//while
}// method
}//class
The problem:
This line does not return the expected value
numOut = (numIn.charAt(i-1) * Math.pow(baseIn, counter++));
For example, in string "10", numOut should be (0*(2*0)) or zero on the first iteration of the for loop. Instead, it returns 48.0.
My Thoughts:
I have a sneaking suspicion it has to do with the charAt() method as debugging the Math.pow() method showed it returning expected values. Suppose it's something to do with all the different variable types? I'm unsure.

Yes you're right charAt is the problem.
When you type let's say "10", the integer value of the character '0' is 48 and for '1' it's 49 according to the encoding table Java uses to encode characters.
If you take a look at it, you see that 0 is encoded as 0x0030 = 3*16^1 = 48, 1 as 0x0031 = 3*16^1 + 1*16^0 = 49 and so on.
If you want to get the numeric value of the character itself you can use
numOut = Character.getNumericValue(numIn.charAt(i-1)) * Math.pow(baseIn, counter++);

The charAt method returns the char of your input, in this case '0', not 0. The Unicode value for the char '0' is not 0, it's 48.
Fortunately, the values '0' through '9' are consecutive Unicode values, 48 through 57 respectively, so you can "subtract" out the 48 by subtracting '0' before multiplying.
numOut = ( (numIn.charAt(i-1) - '0') * Math.pow(baseIn, counter++));
You'll still need to validate that what the user typed is in fact a valid "digit" in the chosen base.
You'll also want to add the values of numOut together to get the decimal result at the end.

Related

How would I add two int that are in the same array to each other and convert them into an int. In the Luhn Algorithm

I am trying to add two parts of an array together to go into an int value. I am using Luhn algorithm to figure out of a credit card is a valid credit card. We are only using 6 digit credit card's just to make sure no one enter's a real credit card number. The part I am confused on is when I go to split a number that is above 10 and add it together. Example if the algorithm was to give me 12 I would need to separate it into 1 and 2 and then add them together to equal 3. I believe I am splitting it currently in the code but when I go to add them together I get some number that makes no since. here is a section of the code with some notes about it.
I have printed out numbers in certain places to show myself what is going on in certain places. I have also added in some comments that say that either the number that is printed out is what is expected, and some comments for when there isn't something I expected
int[] cardNumber = new int[]{ 1,2,3,4,5,5};
int doubleVariablesum = 0;
int singleVariablesum = 0;
int totalSum = 0;
int cutOffVar = 0;
String temp2;
for (int i = cardNumber.length - 1; i >= 0;) {
int tempSum = 0;
int temp = cardNumber[i];
temp = temp * 2;
System.out.println("This is the temp at temp * 2: " + temp);
temp2 = Integer.toString(temp);
if (temp2.length() == 1) {
System.out.println("Temp2 char 0: "+ temp2.charAt(0));
// this prints out the correct number
// Example: if there number should be 4 it will print 4
tempSum = temp2.charAt(0);
System.out.println("This is tempSum == 1: " + tempSum);
// when this goes to add temp2.charAt(0) which should be 4 it prints out //something like 56
} else {
System.out.println("TEMP2 char 0 and char 1: " + temp2.charAt(0) + " " + temp2.charAt(1));
// this prints out the correct number successfully spited
tempSum = temp2.charAt(0) + temp2.charAt(1);
System.out.println("This is tempSum != 1: " + tempSum);
// but here it when I try to add them together it is giving me something
// like 97 which doesn't make since for the numbers I am giving it
}
doubleVariablesum = tempSum + doubleVariablesum;
System.out.println("This is the Double variable: " + doubleVariablesum);
System.out.println();
i = i - 2;
}
Since you are converting the number to a string to split the integer, and then trying to add them back together. You're essentially adding the two characters numerical values together which is giving you that odd number. You would need to convert it back to an integer, which you can do by using
Integer.parseInt(String.valueOf(temp2.charAt(0)))
When adding char symbols '0' and '1' their ASCII values are added - not numbers 0 and 1.
It is possible to use method Character::getNumericValue or just subtract '0' when converting digit symbol to int.
However, it is also possible to calculate sum of digits in a 2-digit number without any conversion to String and char manipulation like this:
int sum2digits = sum / 10 + sum % 10; // sum / 10 always returns 1 if sum is a total of 2 digits
Seems like charAt() type casts into integer value, but the ascii one. Hence for the characters '0' and '1', the numbers 48 and 49 are returned resulting in a sum of 97. To fix this, you could just assign temp2 to (temp / 10) + (temp % 10). Which actually splits a two digit integer and adds their sum.
You need to be aware of the following when dealing with char and String
Assigning the result of charAt(index) to an int will assign the ASCII value and not the actual integer value. To get the actual value you need to String.valueOf(temp2.charAt(0)).
The result of concatenating chars is the sum of the ASCII values.
eg if char c = '1'; System.out.println(c + c); will print "98" not "11".
However System.out.println("" + c + c); will print "11". Note the "" will force String concatenation.

Here is my question with after changes but still no solution

I have upload this code already but it was having some problems and now I have update my code this program does not provide me exact reverse number when I enter 123 it return me 321 but if I enter 001 or 100 it just return me 1 in both case help me to solve this issue
public class Employee {
void fun(int choice) {
int number = choice;
int remander = 0;
int reverse = 0;
while (number >= 1) {
remander = number % 10;> taking remainder here
reverse = reverse * 10 + remander;
number = number / 10;
}
System.out.println(reverse);
}
public static void main(String args[]) {
Employee ob=new Employee();
int choice;
System.out.println("Enter number you want to return");
Scanner obj=new Scanner(System.in);
choice= obj.nextInt();
ob.fun(choice);
}
}
`
Here's a one-liner you can use to convert int to Stream of String numbers, reverse it and return as a String:
Stream.of(Integer.toString(choice).split("")).reduce((c1,c2)->c2+c1).get();
First point: be careful about adding leading 0s to the number. If the number is an integer literal, the leading 0s will actually cause the integer to be interpreted as octal. In this case, 001 octal does, in fact, equal 1 in decimal too, but only due to luck. If you picked another number, it would not give you the result you're expecting; for example, the following code actually prints 63 (not 77):
public class HelloWorld{
public static void main(String []args){
int x = 0077;
System.out.println(x);
}
}
On the other hand, if you're parsing an integer out of a string or using a scanner, the leading 0s will simply be stripped off. For example, the following prints 77:
System.out.println(Integer.parseInt("0077"));
Unfortunately, in neither case will you get 0077, so the leading 0s won't make any difference when you go to do the reverse operation.
Also, think about what happens for 100:
reverse = reverse * 10 + remander;
Reverse is 0 to start with (and 0 * 10 == 0) and 100 % 10 == 0 because 100 is evenly divisible by 10. Put another way, the statement is equal to:
reverse = 0 * 10 + 0;
which clearly equals 0.
You can't do this using Scanner.nextInt() because there is no way to tell if leading zeroes were included once they are converted to an int. And the octal situation is not relevant since Scanner does not process ints that way. So you use either an all String solution and verify the characters are digits or use a hybrid of both math and String methods. I did the latter. The following:
reads in a String
converts to an int
calculates the number of leading zeroes by using the log10 of the
int and the length of the entered string.
Allocates a StringBuilder to hold the result.
Scanner input = new Scanner(System.in);
String val = input.nextLine();
int numb = Integer.valueOf(val);
int len = val.length();
// exponent of the entered number rounded up to the next int.
// This computes the number of digits in the actual int value.
int exp = (int) Math.log10(numb) + 1;
// now reverse the integer and store in the StringBuilder
StringBuilder sb = new StringBuilder();
while (numb > 0) {
sb.append(numb % 10);
numb /= 10;
}
// and append the leading zeros.
System.out.println(sb + "0".repeat(len - exp));
for input of 00001000
prints 00010000
Note that you are still constrained on input by Integer.MAX_VALUE.

Get the Unicode from a Hexadecimal

I've been searching for a solution to my problem for days but can't get a spot-on answer when looking at previously answered questions/ blogs / tutorials etc. all over the internet.
My aim is to write a program which takes a decimal number as an input and then calculates the hexadecimal number and also prints the unicode-symbol of said hexadecimal number (\uXXXX).
My problem is I can't "convert" the hexadecimal number to unicode. (It has to be written in this format: \uXXXX)
Example:
Input:
122 (= Decimal)
Output:
Hexadecimal: 7A
Unicode: \u007A | Unicode Symbol: Latin small letter "z"
The only thing I've managed to do is print the unicode (\u007A), but I want the symbol ("z").
I thought if the unicode only has 4 numbers/letters, I would just need to "copy" the hexadecimal into the code and fill up the remaining places with 0's and it kinda worked, but as I said I need the symbol not the code. So I tried and tried, but I just couldn't get the symbol.
By my understanding, if you want the symbol you need to print it as a string.
But when trying it with a string I get the error "illegal unicode escape".
It's like you only can print pre-determined unicodes and not "random" ones generated on the spot in relation of your input.
I'm only a couple days into Java, so apologies if I have missed anything.
Thank you for reading.
My code:
int dec;
int quotient;
int rest;
int[]hex = new int[10];
char[]chars = new char[]{
'F',
'E',
'D',
'C',
'B',
'A'
};
String unicode;
// Input Number
System.out.println("Input decimal number:");
Scanner input = new Scanner(System.in);
dec = input.nextInt();
//
// "Converting to hexadecimal
quotient = dec / 16;
rest = dec % 16;
hex[0] = rest;
int j = 1;
while (quotient != 0) {
rest = quotient % 16;
quotient = quotient / 16;
hex[j] = rest;
j++;
}
//
/*if (j == 1) {
unicode = '\u000';
}
if (j == 2) {
unicode = '\u00';
}
if (j == 3) {
unicode = '\u0';
}*/
System.out.println("Your number: " + dec);
System.out.print("The corresponding Hexadecimal number: ");
for (int i = j - 1; i >= 0; i--) {
if (hex[i] > 9) {
if (j == 1) {
unicode = "\u000" + String.valueOf(chars[16 - hex[i] - 1]);
}
if (j == 2) {
unicode = "\u00" + String.valueOf(chars[16 - hex[i] - 1]);
}
if (j == 3) {
unicode = "\u0" + String.valueOf(chars[16 - hex[i] - 1]);
}
System.out.print(chars[16 - hex[i] - 1]);
} else {
if (j == 1) {
unicode = "\u000" + Character.valueOf[hex[i]);
}
if (j == 2) {
unicode = "\u00" + Character.valueOf(hex[i]);
}
if (j == 3) {
unicode = "\u0" + Character.valueOf(hex[i]);
}
System.out.print(hex[i]);
}
}
System.out.println();
System.out.print("Unicode: " + (unicode));
}
It's not an advanced code whatsoever, I wrote it exactly how I would calculate it on paper.
Dividing the number through 16 until I get a 0 and what remains while doing so is the hexadecimal equivalent.
So I put it in a while loop, since I would divide the number n-times until I got 0, the condition would be to repeat the division until the quotient equals zero.
While doing so the remains of each division would be the numbers/letters of my hexadecimal number, so I need them to be saved. I choose an integer array to do so. Rest (remains) = hex[j].
I also threw a variable in the called "j", so I would now how many times the division was repeated. So I could determine how long the hexadecimal is.
In the example it would 2 letters/numbers long (7A), so j = 2.
The variable would then be used to determine how many 0's I would need to fill up the unicode with.
If I have only 2 letters/numbers, it means there are 2 empty spots after \u, so we add two zeros, to get \u007A instead of \u7A.
Also the next if-command replaces any numbers higher than 9 with a character from the char array above. Basically just like you would do on paper.
I'm very sorry for this insanely long question.
U+007A is the 3 bytes int code pointer.
\u007A is the UTF-16 char.
A Unicode code pointer, symbol, sometimes is converted to two chars and then the hexadecimal numbers do not agree. Using code pointers hence is best. As UTF-16 is just an encoding scheme for two-bytes representation, where the surrogate pairs for 3 byte Unicode numbers do not contain / or such (high bit always 1).
int hex = 0x7A;
hex = Integer.parseUnsignedInt("007A", 16);
char ch = (char) hex;
String stringWith1CodePoint = new String(new int[] { hex }, 0, 1);
int[] codePoints = stringWith1CodePoint.codePoints().toArray();
String s = "š¯„˛"; // U+1D11E = "\uD834\uDD1E"
You can simply use System.out.printf or String.format to do what you want.
Example:
int decimal = 122;
System.out.printf("Hexadecimal: %X\n", decimal);
System.out.printf("Unicode: u%04X\n", decimal);
System.out.printf("Latin small letter: %c\n", (char)decimal);
Output:
Hexadecimal: 7A
Unicode: u007A
Latin small letter: z

Specific digit detector issue

I have written a small piece of code where you enter a 3 digit number via the command line, and then it detects how many 5's are in the code.
public class fivedet {
public static void main (String[] args) {
String input = args[0];
int[] a = {0,0,0};
int x = 0;
int y = 0;
int z = 0;
for(int i = 0; i<input.length();i++) {
a[i] = input.charAt(i) - 48;
}
if(a[0]==5) {
x=5;
}
if(a[1]==5) {
y=5;
}
if(a[2]==5) {
z=5;
}
System.out.println("5 digits here:" + x + y + z);
}
}
My main question is why I require the -48 term after the input.charAt(i) method in order for each value in a[] to be equal to the actual number I input.
For example I enter
java fivedet 505
and without the -48 the array a[]={53,48,53} instead of a[]={5,0,5} and I unfortunately am not experienced enough with coding java (began learning 3 months ago) to understand why this is happening.
I also do want to develop it to be able to detect different digits and for different lengths of input numbers.
I would appreciate any insight as to why this happens.
Subtracting 48 is a quick but slightly confusing way of converting from a character to an integer. It so happens that the character code for each digit is 48 away from its numeric value.
See this table of ASCII values. (Java uses unicode, not ascii - strings are UTF-16 internally - but the values are valid in this specific case). So the character '0' has the value 48; the character '9' has the value 57.
Another way of doing this would be to take 1-character substrings of input, then call Integer.parseInt() on that string, converting "1" to 1, "2" to 2, etc.
You donā€™t need to convert to int in order to detect character 5. Just count them as chars.
for (char i : args[0].toCharArray()) {
System.out.print(i == '5' ? i : '0');
}
Also this question has good answers to count occurrences of a char in string

Why is myArrayList.size(); producing incorrect/gigantic numbers?

Basically, I'm trying to write a program that converts a number from base 2 to base 10. What I tried doing was translating the process listed on this website under the "Doubling method" into a for loop, but for some reason the numbers I'm getting are way to big.
The basic formula is (2 * previousTotal) + (currentDigit of the ArrayList that holds the user's inputted binary number) = previousTotal.
So for 1011001 in binary, the math would be:
(0 x 2) + 1 = 1
(1 x 2) + 0 = 2
(2 x 2) + 1 = 5
(5 x 2) + 1 = 11
(11x 2) + 0 = 22
(22 x 2) + 0 = 44
(44 x 2) + 1 = 89
The console however, prints out 6185 as the result. I'm thinking it might have something to do with me using an ArrayList of characters, but the charWhole.size() returns 7, which is how many digits are in the user's binary number. As soon as I do charsWhole.get(w); however, I start getting big numbers such as 49. I'd really appreciate some help!
I wrote out this loop, and according to some print statements that I placed throughout the code and my variable addThis seems to be where the problem is. The console prints out a final total of 6185, when 1011001 in base 10 is actually 89.
public static void backto2(){
System.out.println("What base are you coming from?");
Scanner backToB10 = new Scanner(System.in);
int bringMeBack = backToB10.nextInt();
//whole
System.out.println("Please enter the whole number part of your number.");
Scanner eachDigit = new Scanner(System.in);
String theirNumber = eachDigit.nextLine();
String str = theirNumber;
ArrayList<Character> charsWhole = new ArrayList<Character>();
for (char testt : str.toCharArray()) {
charsWhole.add(testt);
}
System.out.println(theirNumber); // User's number
System.out.println(charsWhole); // User's number separated into elements of an ArrayList
System.out.println(charsWhole.size()); // Gets size of arrayList, comes out as 7 which seems fine.
int previousTotal = 0, addThis = 0, q =0;
for( int w = 0; w < charsWhole.size(); w ++) {
addThis = charsWhole.get(w); //current digit of arraylist PROBLEM
q = previousTotal *2;
previousTotal = q + addThis; // previous total gets updated
System.out.println(q);
System.out.println(addThis);
System.out.println(q + " and " + addThis + "equals " + previousTotal);
}
System.out.println(previousTotal);
You are attempting to add a character to an integer. The implicit conversion uses the ASCII value of the character, so that '1' gets converted to 49, not 1, because 49 is the code for the character '1'. Subtract '0' to get the actual integer value.
addThis = charsWhole.get(w) - '0';
This works because the digits 0-9 are represented in ASCII as the codes 48-57, so in effect you will, for '1', subtract 49 - 48 to get 1.
You'll still have to handle cases when the character is outside the range of allowable characters.
EDIT
Java uses Unicode, but for the purposes of the codes for the digits 0-9, the codes are the same (48 thru 57, or 0x30 thru 0x39) in both ASCII and Unicode.
The problem is that you're using the chars rather than the number value they represent. In the line
addThis = charsWhole.get(w);
the value of addThis is the ascii value of the character. For '0', this is 48. Use this instead:
addThis = Integer.parseInt(charsWhole.get(w));
Another suggestion to solve the same problem:
addThis = charsWhole.getNumericValue(w);
See here for more information.

Categories

Resources