Double with custom quantity zero's after dot - java

I have two Integer values and I need create Double value from combining this two values in following way:
A.CB
where:
A — first integer value
B — second integer value
C — zero's to match total length
Basically, CB is always have to be 9 digits in total, that's mean when B = 1 I need that C will be 8 zero's, if B=100 I need C will be 6 zero's.
To get this results:
15.000000001
and
17.000000100
What is the best way to approach this logic in code? I mean I can write custom method to create this logic, but is Java already have something for this case to just use it, without creating custom methods? Better if it's possible without using string format functions (to not convert Integer values to String).

Something like this?
int A = 123, B = 450;
System.out.println(String.format("%.09f", A + 1e-9 * B));
Will print
123.000000450
P.S. String.format is required because of your trailing-zeros-after-the-comma requirement. Those zeros don't actually exist, so you need some way to pad your output, and String.format is a convenient way to do that. If you just want a double value, you don't need String.format.

Divide b / 1000000000.0:
int a = 12;
int b = 123;
double x = a + b / 1000000000.0;
System.out.println(x);
Will print:
12.000000123
Unless b's length is longer than 9 digits, you will get what you want.

int a = 12;
int b = 123;
// How many digits in b?
int blen = (int)Math.log10(b);
// Make a string of zeros
String padding = "00000000".substring(blen);
System.out.println(a + "." + padding + b);
This will fail apart if b is very large, as blen will be larger than the padding, and so substring will fail. Also, negative b will mess things up.

Related

Java Hexadecimal to Decimal conversion: Custom Logic

I am trying to figure out how to convert hex into a string and integer so I can manipulate an RGB light on my arduino micro-controller through it's serialport. I found a good example on the java website, but I'm having a difficult time understanding some of the methods and I am getting hung up. I could easily just copy-paste this code and have it work but I want to fully understand it. I will add comments to my understandings and hopefully someone can provide some feedback.
public class HexToDecimalExample3{
public static int getDecimal(String hex){ //this is the function which we will call later and they are declaring string hex here. Can we declare string hex inside the scope..?
String digits = "0123456789ABCDEF"; //declaring string "digits" with all possible inputs in linear order for later indexing
hex = hex.toUpperCase(); //converting string to uppercase, just "in case"
int val = 0; //declaring int val. I don't get this part.
for (int i = 0; i < hex.length(); i++) //hex.length is how long the string is I think, so we don't finish the loop until all letters in string is done. pls validate this
{
char c = hex.charAt(i); //char is completely new to me. Are we taking the characters from the string 'hex' and making an indexed array of a sort? It seems similar to indexOf but non-linear? help me understand this..
int d = digits.indexOf(c); //indexing linearly where 0=1 and A=11 and storing to an integer variable
val = 16*val + d; //How do we multiply 16(bits) by val=0 to get a converted value? I do not get this..
}
return val;
}
public static void main(String args[]){
System.out.println("Decimal of a is: "+getDecimal("a")); //printing the conversions out.
System.out.println("Decimal of f is: "+getDecimal("f"));
System.out.println("Decimal of 121 is: "+getDecimal("121"));
}}
To summerize the comments, it's primarily the char c = hex.charAt(i); AND the val = 16*val + d; parts I don't understand.
Ok, let's go line for line
public static int getDecimal(String hex)
hex is the parameter, it needs to be declared there, so you can pass a String when you call the function.
String digits = "0123456789ABCDEF";
Yes, this declares a string with all characters which can occur in a hexadecimal number.
hex = hex.toUpperCase();
It converts the letters in the hex-String to upper case, so that it is consistent, i.e. you always have F and never f, no matter which is being input.
int val = 0;
This is the variable where the corresponding decimal value will later be in. We will do our calculations with this variable.
for (int i = 0; i < hex.length(); i++)
hex.length() is the number of characters in the hex-String provided. We execute the code inside this for loop once per character.
char c = hex.charAt(i);
Yes, char represents a single character. We retrieve the character from the hex-String at index i, so in the first iteration it is the first character, in the second iteration the second character and so on.
int d = digits.indexOf(c);
We look which index the character has in the digit-String. In that way we determine the decimal representation of this specific digit. Like 0-9 stay 0-9 and F becomes a 15.
val = 16*val + d;
Let's think about what we have to do. We have the decimal value of the digit. But in hexadecimal we have this digit at a specific position with which it gets multiplied. Like the '1' in '100' is actually not a 1, but 100 * 1 because it is at this position.
10 in hexadecimal is 16 in decimal, because we have 1 * 16. Now the approach here is a little bit complicated. val is not uninitialized. val is 0 at the beginning and then contains the cumulated values from the previous iterations. Since the first character in the String is the highest position we don't know directly with what we have to multiply, because we don't know how many digits the number has (actually we do, but this approach doesn't use this). So we just add the digit value to it. In the consecutive iterations it will get multiplied by 16 to scale it up to the corresponding digit base value. Let me show you an example:
Take 25F as hex number. Now the first iteration takes the 2 and converts it to a 2 and adds it to val. The 16 * val resolves to 0 so is not effective in the first time.
The next iteration multiplies the 2 with 16 and takes the 5 (converted to 5) and adds it to val. So now we have (I split it mathematically so you understand it):
2 * 16 + 5
Next we get the F which is decimal 15. We multiply val by 16 and add the 15.
We get 2 * 256 + 5 * 16 + 16 (* 1), which is actually how you calculate the decimal value of this hex value mathematically.
Another possibility to compute val is:
val += Math.pow(16, hex.length() - i - 1) * d;

Java String "1603" to float 16.03

So I have some java Strings of variable length. It can be from 0 to 999999999 but the last two values should always become the decimal part. I want to convert those strings to float values.
The way I was thinking about was:
String strNum = "200";
strNum = strNum.substring(0, strNum.length()-2) + "." + strNum.substring(str.length()-2);
Float num = Float.parseFloat(strNum);
But this method is quite slow, and I should also add some way to look if the length is bigger than 2, to avoid string index out of range.
My question is: is there any way of doing this in a cleaner and faster way? Otherwise I'll do it as I've been thinking.
Thanks
How about:
float num = Integer.parseInt(strNum) / 100f;
The f after 100 is important, and unless needed, use float, not Float.
String substring function is costly as it creates new Object.So its better to first convert it into number and then divide by 100 to get the desired output.
float num = Integer.parseInt(strNum) / 100f;
If you're sure your string will always be digits only what about a nice simple
float num2 = Float.valueOf(strNum)/100;
Hmm, I type too slow! :)

How do I get the quotient of two ints to round up? (5/2)

I am having some trouble with some extra credit stuff my AP Computer Science teacher assigned. Here are the instructions:
Write a WordScrambler method recombine. This method returns a String created from its two String parameters as follows:
take the first half of word1
take the second half of word2
concatenate the two halves and return the new string
For example, the following lines show some results of calling recombine. Note that if a word has an odd number of letters, the second half of the word contains the extra letter.
here are the examples it gives:
"apple" + "pear" = "apar"
"pear" + "apple" = "peple"
it then says to create method recombine below, only giving one line of code:
private String recombine(String word1, String word2)
then I have to create the rest. I made a test program just to see if my ideas were correct, that I could use length() and substring() to do it (I know I will have to use them some time in it), then I would change the code to work with the private String recombine(word1,word2) bit. So here is my test code:
public class test
{
private static String word1,word2;
public static void main(String[]args){
word1 = "apple";
word2 = "pear";
int length1 = word1.length();
int length2 = word2.length();
System.out.println(length1);
System.out.println(length2);
int half1 = (int)Math.ceil(length1 / 2);
int half2 = length2 / 2;
System.out.println(half1);
System.out.println(half2);
}
}
the output is:
5
4
2
2
As you can see, the variable half1 should be 2.5, but since you cant use half of a letter, it should round up, but even with (int)Math.ceil it still rounds down. When I take out the int, just to see if it works as a double, it gives me an error, 'Possible loss of precision, required:int; found:double;`
The general answer to your question, for the quotient of two positive numbers a and b, is to compute(*) (a + b - 1) / b with the truncating division that most programming languages have. This produces the integer immediately above the real a / b.
In your example, b is 2. The value of length1 / 2 rounded up can be computed as (length1 + 1) / 2.
(*) This is assuming that a + b - 1 can be computed without overflow, which should not be a problem in your example.
The reason your code does not round down is that the division length1 / 2 happens before Math.ceil call, and it happens in integers.
You can round up division without using Math.ceil. For that you add a number that is less than the divisor by one to the number being divided. For example, if you want to round up the result of division by ten, add nine to the dividend:
int res = (d + 9) / 10; // Rounds up
In your case, all you need is to add one to length1:
int half1 = (length1+1) / 2;
The immediate solution is just to do the division in floating point:
int half1 = (int)Math.ceil(length1 / 2.0);
2 is an int literal and 2.0 is a double literal. Java will automatically promote length1 to double in the presence of 2.0 so this is effectively the following:
int half1 = (int)Math.ceil((double)length1 / 2.0);
But as noted by the other two answers, you don't need to use floating point. Furthermore, double only has 53 bits of integral precision so while doing the division in floating point works for an int it may result in error for a long.

String trim coming out with incorrect length

I am using Java to determine the length of a double as part of a larger program. At this time the double is 666 but the length is returning as 5, which is a big problem. I read another question posted here with a solution but that didn't work for me. I will show my code and my attempt at emulating the previous solution with results.
My original code:
double Real = 666;
int lengthTest = String.valueOf(Real).trim().length();
System.out.println("Test: " + lengthTest);
This prints 5
Modifications that didn't work, and were essentially just breaking up the code into multiple lines.
double Real = 666;
String part = Real + "";
part = part.trim();
int newLength = part.length();
System.out.println("new length : " + newLength);
This prints 5 as well.
Obviously, I want this to print how many digits I have, in this case it should show 3.
For a bigger picture if it helps I am breaking down number input into constituent parts, and making sure none of them exceed limits. ie: xx.yyezz where xx can be 5 digits, yy can be 5 digits and zz can be 2 digits. Thank you.
That's because you are using a double.
String.valueOf(Real); // returns 666.0, i.e. length 5
Try casting it to an integer first:
Integer simple = (int) Real;
String.valueOf(simple); // returns 666, i.e. length 3.
A double always puts a decimal place after the number. So the number looks like 666.0. You could see this by printing String.valueOf(Real). You should use an int instead or cast the double to an int:
double Real = 666;
int realInt = (int) Real;
System.out.println(String.valueOf(realInt).length());

How to decode the value encoded as one*100 + two*10 + three?

How to get values one, two and three back?
Is the following approach correct? Looks like no.
int EncodedValue = one*100 + two*10 + three;
// the following decryption is part of another procedure
int one = EncodedValue / 100;
int two = EncodedValue / 10;
int three = EncodedValue % 10;
Assuming two and three are originally in the range 0-9 (otherwise you have ambiguity) you want:
int two = (encodedValue / 10) % 10;
... otherwise it basically gets ten times the one value added to it.
That won't quite work. While I can't speak to the efficiency of the following, it does work:
int encoded = one*100+two*10+three
int one = encoded/100;
int two = (encoded-100*one)/10;
int three = encoded - 100*one - 10*two;
Mind you, this only works if all those variables are a single digit.
It could also be implemented recursively to allow for numbers of any length to be decomposed to their digits, but the it may be less intensive to simply convert to a string and then a character array.

Categories

Resources