In searching for an answer, I used the solution provided in the following link : How to format a Java string with leading zero?
I have the following code that needs to be translated into java:
TRIM(TO_CHAR(123,'000X'))
From what I can tell, it translates the number into hexa and adds some leading zeros.
However, if I give a big value, I get ##### as answer, e.g. for the following code:
TRIM(TO_CHAR(999999,'000X'))
In Java, my current solution is the following:
String numberAsHex = Integer.toHexString(123);
System.out.println(("0000" + numberAsHex).substring(numberAsHex.length()));
It works fine for small numbers, but for big ones, like 999999 it outputs 423f. So it does the transformation, resulting the value f423f and then it cuts a part off. So I am nowhere near the value from Oracle
Any suggestion as to how to do this? Or why are ##### displayed in the Oracle case?
Instead of Integer.toHexString I would recommend using String.format because of its greater flexibility.
int number = ...;
String numberAsHex = String.format("%06x", number);
The 06 means you get 6 digits with leading zeros, x means you get lowercase hexadecimal.
Examples:
for number = 123 you get numberAsHex = "00007b"
for number = 999999you get numberAsHex = "0f423f"
Related
Hi all and thank you for the help in advance.
I have scoured the webs and have not really turned up with anything concrete as to my initial question.
I have a program I am developing in JAVA thats primary purpose is to read a .DAT file and extract certain values from it and then calculate an output based on the extracted values which it then writes back to the file.
The file is made up of records that are all the same length and format and thus it should be fairly straightforward to access, currently I am using a loop and and an if statement to find the first occurrence of a record and then through user input determine the length of each record to then loop through each record.
HOWEVER! The first record of this file is a blank (Or so I thought). As it turns out this first record is the key to the rest of the file in that the first few chars are ascii and reference the record length and the number of records contained within the file respectively.
below are a list of the ascii values themselves as found in the files (Disregard the " " the ascii is contained within them)
"#¼ ä "
"#g â "
"ÇG # "
"lj ‰ "
"Çò È "
"=¼ "
A friend of mine who many years ago use to code in Basic recons the first 3 chars refer to the record length and the following 9 refer to the number of records.
Basically what I am needing to do is convert this initial string of ascii chars to two decimals in order to work out the length of each record and the number of records.
Any assistance will be greatly appreciated.
Edit...
Please find below the Basic code used to access the file in the past, perhaps this will help?
CLS
INPUT "Survey System Data File? : ", survey$
survey$ = "f:\apps\survey\" + survey$
reclen = 3004
OPEN survey$ + ".dat" FOR RANDOM AS 1 LEN = reclen
FIELD #1, 3 AS RL$, 9 AS n$
GET #1, 1
RL = CVI(RL$): n = CVI(n$)
PRINT "Record Length = "; RL
reclen = RL
PRINT "Number of Records = "; n
CLOSE #1
Basically what I am looking for is something similar but in java.
ASCII is a special way to translate a bit pattern in a byte to a character, and that gives each character a numerical value; for the letter 'A' is this 65.
In Java, you can get that numerical value by converting the char to an int (ok, this gives you the Unicode value, but as for the ASCII characters the Unicode value is the same as for ASCII, this does not matter).
But now you need to know how the length is calculated: do you have to add the values? Or multiply them? Or append them? Or multiply them with 128^p where p is the position, and add the result? And, in the latter case, is the first byte on position 0 or position 3?
Same for the number of records, of course.
Another possible interpretation of the data is that the bytes are BCD encoded numbers. In that case, each nibble (4bit set) represents a number from 0 to 9. In that case, you have to do some bit manipulation to extract the numbers and concatenate them, from left (highest) to right (lowest). At least you do not have to struggle with the sequence and further interpretation here …
But as BCD would require 8-bit, this would be not the right interpretation if the file really contains ASCII, as ASCII is 7-bit.
We are building a Python 3 program which calls a Java program. The Java program (which is a 3rd party program we cannot modify) is used to tokenize strings (find the words) and provide other annotations. Those annotations are in the form of character offsets.
As an example, we might provide the program with string data such as "lovely weather today". It provides something like the following output:
0,6
7,14
15,20
Where 0,6 are the offsets corresponding to word "lovely", 7,14 are the offsets corresponding to the word "weather" and 15,20 are offsets corresponding to the word "today" within the source string. We read these offsets in Python to extract the text at those points and perform further processing.
All is well and good as long as the characters are within the Basic Multilingual Plane (BMP). However, when they are not, the offsets reported by this Java program show up all wrong on the Python side.
For example, given the string "I feel 🙂 today", the Java program will output:
0,1
2,6
7,9
10,15
On the Python side, these translate to:
0,1 "I"
2,6 "feel"
7,9 "🙂 "
10,15 "oday"
Where the last index is technically invalid. Java sees "🙂" as length 2, which causes all the annotations after that point to be off by one from the Python program's perspective.
Presumably this occurs because Java encodes strings internally in a UTF-16esqe way, and all string operations act on those UTF-16esque code units. Python strings, on the other hand, appear to operate on the actual unicode characters (code points). So when a character shows up outside the BMP, the Java program sees it as length 2, whereas Python sees it as length 1.
So now the question is: what is the best way to "correct" those offsets before Python uses them, so that the annotation substrings are consistent with what the Java program intended to output?
You could convert the string to a bytearray in UTF16 encoding, then use the offsets (multiplied by 2 since there are two bytes per UTF-16 code-unit) to index that array:
x = "I feel 🙂 today"
y = bytearray(x, "UTF-16LE")
offsets = [(0,1),(2,6),(7,9),(10,15)]
for word in offsets:
print(str(y[word[0]*2:word[1]*2], 'UTF-16LE'))
Output:
I
feel
🙂
today
Alternatively, you could convert every python character in the string individually to UTF-16 and count the number of code-units it takes. This lets you map the indices in terms of code-units (from Java) to indices in terms of Python characters:
from itertools import accumulate
x = "I feel 🙂 today"
utf16offsets = [(0,1),(2,6),(7,9),(10,15)] # from java program
# map python string indices to an index in terms of utf-16 code units
chrLengths = [len(bytearray(ch, "UTF-16LE"))//2 for ch in x]
utf16indices = [0] + list(itertools.accumulate(chrLengths))
# reverse the map so that it maps utf16 indices to python indices
index_map = dict((x,i) for i, x in enumerate(utf16indices))
# convert the offsets from utf16 code-unit indices to python string indices
offsets = [(index_map[o[0]], index_map[o[1]]) for o in utf16offsets]
# now you can just use those indices as normal
for word in offsets:
print(x[word[0]:word[1]])
Output:
I
feel
🙂
today
The above code is messy and can probably be made clearer, but you get the idea.
This solves the problem given the proper encoding, which, in our situation appears to be 'UTF-16BE':
def correct_offsets(input, offsets, encoding):
offset_list = [{'old': o, 'new': [o[0],o[1]]} for o in offsets]
for idx in range(0, len(input)):
if len(input[idx].encode(encoding)) > 2:
for o in offset_list:
if o['old'][0] > idx:
o['new'][0] -= 1
if o['old'][1] > idx:
o['new'][1] -= 1
return [o['new'] for o in offset_list]
This may be pretty inefficient though. I gladly welcome any performance improvements.
I'm developing an desktop application with java, right now I'm at the point of registering person data. One of the fields of the person form is "DocumentTextField" which holds the Identification Document and Number, that's why I tried to use a JFormattedTextField mask, to help user with the format to this field.
Basically, I just used the AbstracFormatterFactory to create the mask:
Mask = UU - ########## to get something like (PP-0123456789)
It does work perfecly on the fly, the user just type "pp0123456789" and the mask become this to "PP-0123456789" the point is the numbers length, as you can see on my mask, i declare 10 numbers (##########) but in fact, It could be lower than 10 numbers or even Higher. It does only work with 10 numbers, if user type lower than 10 numbers, the JFormattedTextField resset to empty, the same thing happen if user type more than 10 numbers.
is there any way to declare the range (numbers length) of this? some document are just 5 numbers (PP-01234).
Thank you so much in advance by reading this and trying to help.
I assume you're using Java 8 for your development. Are you seeing any kind of ParseException?
As per the documentation of the component: https://docs.oracle.com/javase/8/docs/api/javax/swing/text/MaskFormatter.html
When initially formatting a value if the length of the string is less than the length of the mask, two things can happen. Either the placeholder string will be used, or the placeholder character will be used. Precedence is given to the placeholder string.
According to the example:
MaskFormatter formatter = new MaskFormatter("###-####");
formatter.setPlaceholderCharacter('_');
setPlaceHolderCharacter method can help you with your problem.
int diny6h = Integer.parseInt(Integer.valueOf(diny6).toString(), 10);
int diny7h = Integer.parseInt(Integer.valueOf(diny7).toString(), 10);
diny6h=diny6h-32;
diny7h=diny7h-32;
System.out.println(diny6h + " + " + diny7h);
}
Incoming: diny6=30 diny7=20
printed: diny6h=16 diny7h=00
What i want: diny6h=10 diny7h=00
What am i doing wrong here?
EDIT:
well.. the numbers are send as hexadezimals and received as decimals, because the other numbers in the block (not diny6 and 7, but diny1 to diny5) are needed as hexadezimals. but diny6 and 7 are needed as decimals but im not able to get them the way i want i want to send a 35(hex) it comes in as 53(dec) and should be pirnted out as 10(dec). Same issue: want to send a 20(hex) it comes as a 32(dec) and should printed as 0
In short:
I send the 35, received as 53, but i need the 35 to reduce it by 20 and get the 15... how do i do that?
EDIT:
I am sorry for my yesterdays cofusing. WHat i need is to convert my received value to a BCD-number... nothing with hex ^^ should i delete this question now?
nothing is wrong.
for diny6:
30(hex) - 32(dec) = 30(hex) - 20(hex) = 10(hex) = 16(dec)
similarly for diny7.
integers by default are printed in decimal, thats why you get 16.
if you want to print the number in hex format do something like:
System.out.println(String.format("%x",diny6));
update:
i'm afraid you don't fully understand mathematical bases. hex and dec are just representations, an int variable isn't decimal or hex - it is just a number.
1. read the string representation of the number.
2. do whatever computations you need (and dont concern your self with the base during this stage).
3. print the result either as decimal or hex using format strings.
4. read up about the subject.
Was my own fault, misunderstood the meaning of what i wanted to do and ignored some hardware relevant requirements. Question totally wrong asekd.
I'm using a GPS web service that is retrieving information in the following format (numbers changed up a bit for privacy reasons but format is unchanged):
X: 32 14 08.47S
Y: 140 17 12.82E
What I need to do is convert these to decimal co-ordinates (xx.xxxxxxxxx, xx.xxxxxxxxx). Are there any simple snippets of Java code that can do this task? If not, I'm happy to look at resources that explain how to achieve this in a different language.
If the degrees, minutes, and seconds are guaranteed to be separated a single space you could do something as simple as
String line = read_a_line_from_file();
String[] tokens = line.split(" ");
That will leave you with
tokens[0] = "X:"
tokens[1] = "32"
tokens[2] = "14"
tokens[3] = "08.47S"
You could then Double.parseDouble() the ones after tokens[0] to get the numeric degrees, minutes, and seconds which you would then combine to get the decimal degrees. Of course for tokens[3] you'd have to strip off the final N/S/E/W character before doing the parse.
Another more elegant possibility might be to take advantage of the fact that instances of MessageFormat and its subclasses can be use for parsing a string of a given format as well as formatting such a string.