I am trying to convert a decimal into a character.
I have my alphabet which has been converted to a charArray
String alphabet = "abcdefghijklmnopqrstuvwxyz";
alpha = alphabet.toCharArray();
I was using binary numbers so values only from 0 to 255, however when I try to execute this code, it does not work.
private int toChar(int encryptCode){
int base = 26;
int characterSteps = (encryptCode/255)*base;
char character = alpha[characterSteps];
return character;
Lets say I have the decimal 78, 78/255 * 26 would give 7.95 (being int rounds to 8)
It should look up the alpha array and give 'h'. But every character gives 'a' meaning that (encryptCode/255)*base isn't working as intended.
Kevin is right in the comments. Try rearranging your formula like this:
int characterSteps = (encryptCode*base)/255;
change
int characterSteps = (encryptCode/255)*base;
to
int characterSteps = (int) (encryptCode/255.0)*base;
and you are done! 255.0 will cause broadening on encryptCode and base, and then cast to int.
Lets say I have the decimal 78, 78/255 * 26 would give 7.95 (being int rounds to 8)
Casting float/double to int will result in truncation and not round off. 7.95 will be truncated to 7 and not 8. To round the integer, use this:
double x = (encryptCode/255.0)*base;
int characterSteps = (int) Math.round(x);
Happy Coding! :)
Related
I am trying to divide two integer and get a decimal number
I am keep getting 0 result when I divide 10/29
I would like to get 0.34
my code is :
private int totalCount_Games;
private int totalCount_Hints_Statistics;
double avgHints;
avgHints=totalCount_Hints_Statistics/totalCount_Games;
In Java, when you divide two integers, the result is another integer.
In your case, 10/29 will result in 0 as you mentioned. If you want to get the results of these in floating digits, then change the above two integers to float or double.
In that case, the result for the above calculation will be 0.34.
PS: This is really basic. You should do more research in the official java site for documentation on datatypes.
The result of a int division is another int, rounded.
Casting int to double (or float) in the expression part will make the division occurs on doubles instead of int, note that this is different from casting the result from the int division to double.
int i = 5, b = 10;
double result = ((double)i)/((double)b);
result is 0.5
The above code will result in 0.0 as int/int will always be a int which is further type casted into double thus output is 0.0
Use the below code, Using big decimal for Rounding
double totalCount_Games_double = totalCount_Games;
double totalCount_Hints_Statistics_double = totalCount_Hints_Statistics;
double value = totalCount_Hints_Statistics/totalCount_Games_double;
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(2, RoundingMode.HALF_UP);
Suppose i have background color set as #AF000000(AARRGGBB) in android.
I want value of alpha channel(AA) in decimal (0-255) which is going to be 175.
How to accomplish that programatically?
Here is a pure Java solution that doesn't use the Android-specific getAlpha() method.
Do you have this value stored in a String or an int? If you have it in a String, first get rid of the # character then convert it to an int:
String hexString = "#05000000";
int color = Integer.parseInt(hexString.replaceAll("#", ""), 16);
Then we need to make some bit manipulation. This hex color representation means (in ARGB mode) you have the values #AARRGGBB. That is 2 bytes for each channel, including the alpha one. To get just the alpha channel (the AA part of the hex value), we need to "push it 6 bytes to the right" (Java is a Big Endian languange) so we can end up with something like #000000AA. Since each byte is comprised of 8 bits, we have to "push" the alpha values 6 * 8 = 24 bits "to the right":
int alpha = color >> 24;
This process is called Bit Shifting. All the rightmost RGB values are discarded and we then have the alpha value stored in an int with a decimal value between 0 and 255.
EDIT: If you already have the alpha value as returned from getAlpha(), you can always multiply it by 255 and floor it:
int alpha = Math.floor(myView.getAlpha() * 255);
You may convert your HEX to Decimal Simply use,
int i= Integer.parseInt(HEX_STR,16);
or if you need to pass long hex value means use like,
public static long hexToLong(String hex) {
return Long.parseLong(hex, 16);
}
To get each individual int value:
int argb = Color.parseColor("#00112233");
int alpha = 0xFF & (argb >> 24);
int red = 0xFF & (argb >> 16);
int green = 0xFF & (argb >> 8);
int blue = 0xFF & (argb >> 0);
I have a TextView with an OnTouchListener. What I want is the character index the user is pointing to when I get the MotionEvent. Is there any way to get to the underlying font metrics of the TextView?
Have you tried something like this:
Layout layout = this.getLayout();
if (layout != null)
{
int line = layout.getLineForVertical(y);
int offset = layout.getOffsetForHorizontal(line, x);
// At this point, "offset" should be what you want - the character index
}
Hope this helps...
I am not aware of a simple direct way to do this but you should be able to put something together using the Paint object of the TextView via a call to TextView.getPaint()
Once you have the paint object you will have access to the underlying FontMetrices via a call to Paint.getFontMetrics() and have access to other functions like Paint.measureText() Paint.getTextBounds(), and Paint.getTextWidths() for accessing the actual size of the displayed text.
While it generally works I had a few problems with the answer from Tony Blues.
Firstly getOffsetForHorizontal returns an offset even if the x coordinate is way beyond the last character of the line.
Secondly the returned character offset sometimes belongs to the next character, not the character directly underneath the pointer. Apparently the method returns the offset of the nearest cursor position. This may be to the left or to the right of the character depending on what's closer by.
My solution uses getPrimaryHorizontal instead to determine the cursor position of a certain offset and uses binary search to find the offset underneath the pointer's x coordinate.
public static int getCharacterOffset(TextView textView, int x, int y) {
x += textView.getScrollX() - textView.getTotalPaddingLeft();
y += textView.getScrollY() - textView.getTotalPaddingTop();
final Layout layout = textView.getLayout();
final int lineCount = layout.getLineCount();
if (lineCount == 0 || y < layout.getLineTop(0) || y >= layout.getLineBottom(lineCount - 1))
return -1;
final int line = layout.getLineForVertical(y);
if (x < layout.getLineLeft(line) || x >= layout.getLineRight(line))
return -1;
int start = layout.getLineStart(line);
int end = layout.getLineEnd(line);
while (end > start + 1) {
int middle = start + (end - start) / 2;
if (x >= layout.getPrimaryHorizontal(middle)) {
start = middle;
}
else {
end = middle;
}
}
return start;
}
Edit: This updated version works better with unnatural line breaks, when a long word does not fit in a line and gets split somewhere in the middle.
Caveats: In hyphenated texts, clicking on the hyphen at the end of a line return the index of the character next to it. Also this method does not work well with RTL texts.
I'm developing an android application and i need to know the number of characters that could be shown in one line to determine the number of lines of my string with some method .
How could do this ?
tanks a lot .
This should do the job for you (give or take a few mistakes from coding without an ide :-/ )
int countLineBreaks(final TextView view, final String toMeasure) {
final Paint paint = textView.getPaint(); // Get the paint used by the TextView
int startPos = 0;
int breakCount = 0;
final int endPos = toMeasure.length();
// Loop through the string, moving along the number of characters that will
// fit on a line in the TextView. The number of iterations = the number of line breaks
while (startPos < endPos) {
startPos += paint.breakText(toMeasure.substring(startPos, endPos),
true, tv.getWidth(),(float[]) null);
lineCount++;
}
// Line count will now equal the number of line-breaks the string will require
return lineCount;
}
..you get the idea ;-)
Every character has its own width.
As any String which contains 10 characters is not same to another String which also contains 10 char.
u can set it by --> textView.setTypeface(Typeface.MONOSPACE);
Monospace typeface works for making will regular char equal width.
Then u can do any stuff to get that how many characters could be placed in one line?
You can try this
set the Typeface.MONOSPACE as geet suggested. then do the following
Paint.measureText(String s) returns the width of the String s. By using this you can get the required width of 1 character. And from the View.getwidth() method you can get the width of the view. So from these two values you can calculate
try this:
int totalLine = textView.getMeasuredHeight() / textView.getLineHeight();
I am using the following code to get the R,G,B values for a grayscale image(they all will be the same)
But the output gives me negative values.
Why is this so? I am totally confused.
for (int i=0;i<bb.getWidth();i++){
for (int j=0;j<bb.getHeight();j++){
long temp=bb.getPixel(i, j);
int a=(int)temp;
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(a );
byte[] result = b.array();
Log.d("gray value is=", String.valueOf((int)result[1]));
// Log.d("gray value is=", String.valueOf(getLastBytes(a)));
}
}
Here result[1] should correspond to the 'R' value. So how is it negative?
Try this
long temp=bb.getPixel(i, j);
R = Color.red(temp);
G = Color.green(temp);
B = Color.blue(temp);
It is because of all type changes, the casting associated with it, and the fact that those types are signed.
First of all, the initial return value of getPixel() is an int (32-bits or 4 bytes, one byte for ARGB). Placing it into a long seems unnecessary here, because you just cast it back into an int. But so far so good.
When you get the byte array, you are correct that the four bytes for ARGB are in order so result[1] should be the Red value. However, when you implicitly cast that byte into an int in your log statement, a problem happens.
Because the int is four bytes long, and both int and byte are signed types, sign extension applies to the result, i.e.
The byte 0x48 will extend into an int as 0x00000048
The byte 0x88 will extend into an int as 0xFFFFFF88
So when you print the result to the log, it interprets the decimal value of your data to be a negative number. Admittedly, even if you didn't cast and just printed the value of byte, that type is still signed (i.e. it goes from -128 to 127 and not 0 to 255, and 0x88 means -120), so the log output would be the same.
If you want to log out the actual 0-255 value, modify your code to bitmask the pixel data to defeat sign extension in the int:
int red = (int)(result[1] & 0xFF);
Log.d("gray value is=", String.valueOf(red));