| By Nicole Redmond, David Dieterle | Article Rating: |
|
| February 18, 2009 07:00 PM EST | Reads: |
2,821 |
When looking for a language to modernize legacy applications, Java is a strong and viable contender. It offers portability, maintainability, extensibility, and cost effectiveness. However, for some heavy algorithmic time-critical scientific applications, Java may not be an engineer's first choice for modernization. Many algorithmic-intensive scientific applications require bit-wise manipulations for which Java has no real clean solution. This is all true, but with a little creativity, Java can handle bit-wise manipulations.
There is no Java bit class. Java handles bit-wise comparisons and shifting, but currently there's no Java class that handles a native bit type. The closest native type in size is a Boolean. Varied sized data fields require a container that can handle various size data fields and still treat the data fields as objects.
Java does have a BitSet class that can handle bits. The Java BitSet class implements a vector of bits that expands as needed. Each item in the
vector has a Boolean value. A BitSet is really a vector of bits, and can be used to efficiently store a lot of on-off information. The minimum size of the BitSet is 64-bits; the same length as a long. If you're storing a value that's a smaller size such as 3-bits the BitSet is excessively large and inefficient. If efficient access is required accessing bits from a BitSet would be slower than accessing an array of some native type.
Based on these two limiting factors creating a storage unit to handle the storage of the bits would be a better approach. The most ideal situation would be to have a bit native type. Since there's no Bit class available in Java, creating a class to handle bits of variable size would be the best solution.
A creative Java developer can create his own Java bit class simply by extending the Boolean class:
public class MyBitType extends Boolean {}
The newly defined MyBitType can then be used to hold either a single bit or multiple bits by creating an array of MyBitType. The array of MyBitType could then be various lengths depending on the user's need.
The problem with the MyBitType class is that inside a Java Virtual Machine (JVM) there are no instructions specifically for Booleans. A Boolean doesn't have a defined size and its JVM implementation is free to store the Boolean in any fashion it chooses. Often integer operations are used on bits so it's very possible that a single Boolean is stored as an integer and an array of Booleans could be stored as an array of bytes which is very inefficient in terms of both storage and access. This, of course, would need to be verified by looking at the source code for the JVM being used.
An even more creative software engineer might choose to create a BitContainerType class. This BitContainerType class would define the size of the container to store the data values. By creating a defined size, the user should gain efficiency.
In addition to containing a data field value, this BitContainerType class can contain the bit starting position and could be used to assemble messages based on the starting position and the length of the data field. This makes the data an object that can be manipulated in Java (see Listing 1).
The BitContainerType for a message can be defined as shown in Listing 2.
Besides defining the values, the BitContainerType class has get and set methods for accessing the data field values. The data fields are now BitContainerType objects that can be reused by other parts of the application. The defined sized objects can now be stored in the data base, interface with the model code, or be reused by any of the application code.
More importantly, the varied sized data fields are objects with a length and value that can be put together or "fiddled with" to make a message. The objects must be shifted and masked to assemble them as a contiguous stream of bits. This stream can be efficiently parsed by the receiving interface to access fields defined anywhere in the message. Note from the sample code above that the data values are all different lengths and that a different number of bits would be very tedious and inefficient to process without a bit-like structure like the BitContainerType.
The individual messages will be created as a byte array that will consist of 128 bytes. If the values are always going to stay the same, no further processing is required.
If the data is dynamic and constantly changing, then a methodology for changing the values contained in the BitContainerType data objects must be defined. The ultimate goal is to communicate with the interfaces via the messages. The messages must be built before being sent. The messages are built by combining the varied size BitContainerType objects in the specified order to be sent.
The BitContainerTypes are all added to a byte array that will be sent to the interface via the standard message protocol TCP/IP. The data values can be larger than a byte or smaller than a byte. Because the BitContainerTypes are different lengths, each of the different sizes need to be handled. If the BitContainerType is the same size as a native type it's simple to convert the bits to the byte array. A BitOperations class was created to handle these conversions.
For example converting an integer to a byte array would use the following code from the BitOperations class:
public static byte[] intToByteArray(int myInteger) {
byte[] value = new byte[4];
value[0] = (byte) ((myInteger >> 24) & 0x000000FF);
value[1] = (byte) ((myInteger >> 16) & 0x000000FF);
value[2] = (byte) ((myInteger >> 8) & 0x000000FF);
value[3] = (byte) (myInteger & 0x00FF);
return value;
}
If the BitContainerType is not the same size as a native type, the conversion is more difficult. There are two distinct cases that must be handled. The first is a data object that is less than eight bits and the second is the case where the data object is greater than eight bits. In the latter, the object will "straddle" two or more bytes.
For example:
BitContainerType unused8 = new BitContainerType (4,3,0);
BitContainerType customerCode = new BitContainerType (6,5,42);
BitContainerType customerId = new BitContainerType,(6,5,55);
In this example, the first data value is four bits long, the second data value is six bits long and the final data value is six bits long. The interface is expecting a message with the following bits: 0000 1010 1011 0111.
To send 0000 1010 1011 0111, the first four bits must be added to the first byte in the byte array, the second data value, with a start bit location of four, must be added to the end of the first byte in the byte array and added to the first part of the second byte in the byte array, essentially straddling two bytes. Finally the last six bits, with start bit location 10, must be placed at the end of the second byte in the byte array. The bits will need to be shifted and masked to add them to the bytes correctly.
The sample code in Listing 3 handles both of these cases. In the case where the data object doesn't fill the entire byte, there's a check for the number of bits along with a variable that holds the location for the next bit and a variable to keep track of which byte the processing is in.
There's also a check to determine if the data object is greater than eight bits or overlaps onto a second byte. In this case, the byte array is incremented and the bits are added to the next byte in the byte array.
The final result is a byte array with the data in the correct order ready to be sent to the interface as APIs. The byte array is then sent to a message API that creates a byte buffer consisting of a predefined header and the body. The body consists of the byte array of data fields added to the byte buffer.
Conclusion
The creative solution of creating a BitContainerType class allows the user to convert the data fields into objects of variable length bits that can be accessed and processed efficiently. This lets the developer quickly and easily create formatted interface messages. It also lets the user be more efficient when it comes to data storage which is a plus for algorithmic-intensive scientific applications that require bitwise manipulations. While Java doesn't have a bit class, it's flexible enough to let the user create his own "bit type" and BitContainerType classes. I hope this article has convinced you that Java offers a solution for algorithmic-intensive scientific applications that require bitwise manipulations and is a good alternative to other languages.
Published February 18, 2009 Reads 2,821
Copyright © 2009 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Nicole Redmond
Nicole Redmond has 14 years of software IT experience, including 9 years of Java development. She is currently developing enterprise applications that integrate COTS and legacy software with Java and web applications. Nicole is a senior member of the engineering staff with Lockheed Martin Corporation working out of Moorestown, NJ.
More Stories By David Dieterle
David Dieterle has 10 years' experience in Java and database development, with the last 8 years in enterprise software development. He is currently involved in numerous development projects focusing on integration of stove-piped solutions and web development. David is a senior member of the engineering staff with Lockheed Martin Corporation working out of Moorestown, NJ.
![]() |
sflanaga 05/26/09 11:02:00 PM EDT | |||
I have a post concerning java on reading binary data using a C idiom that uses structs and bit-fields. I really do miss this idiom in java since it made this type of thing easy. However, instead of relying on a language builtins that the C bit field relies on, this uses java Annotations with reflection and could be extended for other strange file or network types. I have written how to read, but did not write up a "write" routine. The write could just as well be done. I thought it meshed well with this article. Take a look |
||||
- Kindle 2 vs Nook
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- Confessions of a Ulitzer Addict
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- It's the Java vs. C++ Shootout Revisited!
- Cloud Computing Can Revitalize Your Career as Software Developer
- IBM Could "Reinvent" Java: Mills
- Oracle & Cloud Computing: Exclusive Q&A with SVP Richard Sarwal
- A Brief History of Cloud Computing
- Kindle 2 vs Nook
- Cloud CEOs, CTOs & SVPs to Speak at 4th International Cloud Computing Expo
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- The Difference Between Web Hosting and Cloud Computing
- Cloud Computing Expo: Exclusive Q&A with Yahoo! SVP Cloud Computing
- Ajax in RichFaces 3.3, JSF 2 and RichFaces 4
- Confessions of a Ulitzer Addict
- My Thoughts on Ulitzer
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- The i-Technology Right Stuff
- JavaServer Faces (JSF) vs Struts
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate
- What's New in Eclipse?
- Why Do 'Cool Kids' Choose Ruby or PHP to Build Websites Instead of Java?
- i-Technology Predictions for 2007: Where's It All Headed?









































