Most elegant way to convert a byte to an int in Java - java

Example code:
int a = 255;
byte b = (byte) a;
int c = b & 0xff; // Here be dragons
System.out.println(a);
System.out.println(b);
System.out.println(c);
So we start with an integer value of 255, convert it to a byte (becoming -1) and then converting it back to an int by using a magic formula. The expected output is:
255
-1
255
I'm wondering if this a & 0xff is the most elegant way to to this conversion. checkstyle for example complains about using a magic number at this place and it's not a good idea to ignore this value for this check because in other places 255 may really be a magic number which should be avoided. And it's quite annoying to define a constant for stuff like this on my own. So I wonder if there is a standard method in JRE which does this conversion instead? Or maybe an already defined constant with the highest unsigned byte value (similar to Byte.MAX_VALUE which is the highest signed value)
So to keep the question short: How can I convert a byte to an int without using a magic number?
Ok, so far the following possibilities were mentioned:
Keep using & 0xff and ignore the magic number 255 in checkstyle. Disadvantage: Other places which may use this number in some other scope (not bit operations) are not checked then, too. Advantage: Short and easy to read.
Define my own constant for it and then use code like & SomeConsts.MAX_UNSIGNED_BYTE_VALUE. Disadvantage: If I need it in different classes then I have to define my own constant class just for this darn constant. Advantage: No magic numbers here.
Do some clever math like b & ((1 << Byte.SIZE) - 1). The compiler output is most likely the same because it gets optimized to a constant value. Disadvantage: Pretty much code, difficult to read. Advantage: As long as 1 is not defined as magic number (checkstyle ignores it by default) we have no magic number here and we don't need to define custom constants. And when bytes are redefined to be 16 bit some day (Just kidding) then it still works because then Byte.SIZE will be 16 and not 8.
Are there more ideas? Maybe some other clever bit-wise operation which is shorter then the one above and only uses numbers like 0 and 1?

This is the standard way to do that transformation. If you want to get rid of the checkstyle complaints, try defining a constant, it could help:
public final static int MASK = 0xff;
BTW - keep in mind, that it is still a custom conversion. byte is a signed datatype so a byte can never hold the value 255. A byte can store the bit pattern 1111 1111 but this represents the integer value -1.
So in fact you're doing bit operations - and bit operations always require some magic numbers.
BTW-2 : Yes, there is a Byte.MAX_VALUE constant but this is - because byte is signed - defined as 27-1 (= 127). So it won't help in your case. You need a byte constant for -1.

Ignore checkstyle. 0xFF is not a magic number. If you define a constant for it, the constant is a magic constant, which is much less understandable than 0xFF itself. Every programmer educated in the recent centuries should be more familiar with 0xFF than with his girlfriend, if any.
should we write code like this?
for(int i = Math.ZERO; ... )

Guava to the rescue.
com.google.common.primitives.UnsignedBytes.toInt

Java 8 provides Byte.toUnsignedInt and Byte.toUnsignedLong (probably for really big bytes) methods:
byte b = (byte)255;
int c = Byte.toUnsignedInt(b); // 255
long asLong = Byte.toUnsignedLong(b); // 255

I wrote a method for this like
public static int unsigned(byte x) {
return int (x & 0xFF);
}
which is overloaded for short and int parameters, too (where int gets extended to long).
Instead of 0xFF you could use Byte.MAX_VALUE+Byte.MAX_VALUE+1 to keep FindBug shut, but I'd consider it to be an obfuscation. And it's too easy to get it wrong (s. previous versions).

Related

objective-c code convert for java code

I have a objective-c code.
but I want to convert to java code.
I know objective-c's NSData equals java's byte[].
but I don't know about the equivalent of rest of the keywords.
Objective-C CODE
NSData * updatedValue = characteristic.value;
uint8_t* dataPointer = (uint8_t*)[updatedValue bytes];
uint8_t flags = dataPointer[0]; dataPointer++;
int32_t tempData = (int32_t)CFSwapInt32LittleToHost(*(uint32_t*)dataPointer); dataPointer += 4;
int8_t exponent = (int8_t)(tempData >> 24);
int32_t mantissa = (int32_t)(tempData & 0x00FFFFFF);
if( tempData == 0x007FFFFF )
{
NSLog(#"Invalid temperature value received");
return;
}
float tempValue = (float)(mantissa*pow(10, exponent));
self.tempString = [NSString stringWithFormat:#"%.1f", tempValue];
Please help me
You could try
Objective c to Java converter
Incase if you need your java code to be converted to Objective C
Java to Objective c converter
Reference
Do not attempt convert it to Java, determine what it does and write it in Java.
A little educated guesswork based on your knowledge of programming should get you a long way to understanding the code. This is a great advantage of programming languages over natural languages, understand programming and you can usually make a good educated guess at the meaning of a fragment of code even if you don't know the language. In natural languages the same simply does not hold, knowing, say, French is little help in reading Hindi!
So let's see, uint8_t is probably a type, what type could it be? Well int sounds a lot like integer, 8 is probably the size of the integer in bits - it occurs in the second line which also contains the word bytes, and the u probably means unsigned. So guess that uint8_t is an unsigned 8-bit integer. Now look at the other type-like words, do they make sense in the same way?
So what is the code doing? Well you've figure out that NSData * is "like" byte[], so what would the code set flags to? The first byte in the array maybe? How about tempData? Well there is a 32 in the types here, and that is four bytes.
Having got tempData what do the code do? Some manipulation which results in tempValue which is a float. Maybe float is a 32-bit floating point number? Which is of course what it is in Java.
However here you're going to hit a wall. If you look up how a 32-bit floating-point number is represented in IEEE 754 - the most common way to represent floating point numbers - you will discover that it is stored in binary with the mantissa being a faction (see Wikipedia).
Now look at the code, pow(10, exponent) looks a lot like 10 to the power, not 2 to the power. And does the mantissa look like its being treated as a fraction?
So whatever for those 4 bytes you've guessed are being converted into a float it looks like either (a) they are not a typical 32-bit float or (b) the Objective-C code is wrong...
So back to the first point - determine what this code is meant to do and then write it directly in Java, don't try to convert it.
HTH

Valid way to move bits in java

I'm working on an assignment for school and I'm getting strange output. So, I figured I should start checking some of my more basic methods before I get to the fancier ones. The question I have is this:
would the method
public static short get16(byte a, byte b){
return (short)(a*Math.pow(2,8)+b)
}
return a short where the first 8 bits are byte a and the last 8 bits are byte b?
I don't see why it wouldn't, since multiplying by 2^8 would be the same as left shifting 8 bits to the left. And adding the second byte would make up for the 8 0's achieved by multiplying by 2^8. Is this correct?
I wouldn't recommend using Math.pow to compute 256. pow is notoriously hard to implement correctly; some extant implementations don't even get the exact cases right!
Also, bytes in Java are signed, so you probably want to say (a&255) and (b&255) rather than just a and b. Sign extension will ruin everything for you.
Some things you should know:
"Math.pow" is a floating-point function. Don't do integer calculation by calling floating-point functions and then rounding the result.
Java virtual machine is internally a 32-bit system. All "byte" and "short" mathematical expressions are internally evaluated as "int". Even an addition of two bytes goes internallly like this: 1) convert the bytes to ints, 2) add the ints, 3) convert the lower 8 bits to byte.
The correct way is:
return (short) ((a << 8) + (b & 255));
or
return (short) ((a << 8) | (b & 255));
When "byte" is converted to "int", the sign bit gets copied into the new bits. For example 0b01010101 becomes 0b00000000_00000000_00000000_01010101, because the first bit was 0, but 0b10101010 becomes 0b11111111_11111111_11111111_10101010.

How the bits are stored in C++, How to represent similar functionality in Java

I have in C++:
typedef struct _msk {
char abc[4];
//some more variables
}
_msk mr;
if (some condition >= 70) {
mr.abc[0] |= 0xC0; //C0 in binary 11000000
mr.abc[1] |= 0x20; //20 in binary 100000
mr.abc[2] |= 0x44; //44 in binary 1000100
}
here OR operation is goin on after which the value will be stored.
So in memory is it like (0th)11000000(1st)100000(2nd)1000100 as these are in array? how many bits can be actually stored in [4](total 0+1+2+3+4).
In Java:
private BitSet abc = new BitSet(40);
if a updation or modification of bits are required we can utilise set or get methods provided by the bitset class.
In java if we need to carry out the OR operation we need to add the 0's in the suffix to have the same result. Which we can avoid in c++??
Thanks
So in memory is it like
(0th)11000000(1st)100000(2nd)1000100
as these are in array?
almost: (0th)11000000(1st)00100000(2nd)01000100
how many bits can be actually stored
in [4](total 0+1+2+3+4).
Not 0+...+4, but 0+...+3, 4 chars of size 8 bits = 32 bits (indices: 0, 1, 2, 3)
And you can still use the bitwise operators in Java - not entirely sure what you are asking regarding the Java code ??
Since you are using the |=, you are actually doing mr.abc[0] = mr.abc[0] | 0xC0;
So this means the result depends on the original value of mr.abc[0], which may or may not be 0.
Also there are 8 bits in a char(1 byte)..so with 4 elements in the array there are 32 bits total.
Java uses the exact same notations for all the bitwise operations. I am not sure where you are going with the BitSet.

Java: Unsigned numbers

Is there a way in Java to use unsigned numbers like in (My)SQL?
For example: I want to use an 8-bit variable (byte) with a range like: 0 ... 256; instead of -128 ... 127.
No, Java doesn't have any unsigned primitive types apart from char (which has values 0-65535, effectively). It's a pain (particularly for byte), but that's the way it is.
Usually you either stick with the same size, and overflow into negatives for the "high" numbers, or use the wider type (e.g. short for byte) and cope with the extra memory requirements.
You can use a class to simulate an unsigned number. For example
public class UInt8 implements Comparable<UInt8>,Serializable
{
public static final short MAX_VALUE=255;
public static final short MIN_VALUE=0;
private short storage;//internal storage in a int 16
public UInt8(short value)
{
if(value<MIN_VALUE || value>MAX_VALUE) throw new IllegalArgumentException();
this.storage=value;
}
public byte toByte()
{
//play with the shift operator ! <<
}
//etc...
}
You can mostly use signed numbers as if they were unsigned. Most operations stay the same, some need to be modified. See this post.
Internally, you shouldn't be using the smaller values--just use int. As I understand it, using smaller units does nothing but slow things down. It doesn't save memory because internally Java uses the system's word size for all storage (it won't pack words).
However if you use a smaller size storage unit, it has to mask them or range check or something for every operation.
ever notice that char (any operation) char yields an int? They just really don't expect you to use these other types.
The exceptions are arrays (which I believe will get packed) and I/O where you might find using a smaller type useful... but masking will work as well.
Nope, you can't change that. If you need something larger than 127 choose something larger than a byte.
If you need to optimize your storage (e.g. large matrix) you can u can code bigger positive numbers with negatives numbers, so to save space. Then, you have to shift the number value to get the actual value when needed. For instance, I want to manipulate short positive numbers only. Here how this is possible in Java:
short n = 32767;
n = (short) (n + 10);
System.out.println(n);
int m = (int) (n>=0?n:n+65536);
System.out.println(m);
So when a short integer exceeds range, it becomes negative. Yet, at least you can store this number in 16 bits, and restore its correct value by adding shift value (number of different values that can be coded). The value should be restored in a larger type (int in our case). This may not be very convenient, but I find it's so in my case.
I'm quite new to Java and to programming.
Yet, I encountered the same situation recently the need of unsigned values.
It took me around two weeks to code everything I had in mind, but I'm a total noob, so you could spend much less.
The general idea is to create interface, I have named it: UnsignedNumber<Base, Shifted> and to extend Number.class whilst implementing an abstract AbstractUnsigned<Base, Shifted, Impl extends AbstractUnsigned<Base, Shifted, Impl>> class.
So, Base parameterized type represents the base type, Shifted represents actual Java type. Impl is a shortcut for Implementation of this abstract class.
Most of the time consumed boilerplate of Java 8 Lambdas and internal private classes and safety procedures. The important thing was to achieve the behavior of unsigned when mathematical operation like subtraction or negative addition spawns the zero limit: to overflow the upper signed limit backwards.
Finally, it took another couple of days to code factories and implementation sub classes.
So far I have know:
UByte and MUByte
UShort and MUShort
UInt and MUInt
... Etc.
They are descendants of AbstractUnsigned:
UByte or MUByte extend AbstractUnsigned<Byte, Short, UByte> or AbstractUnsigned<Byte, Short, MUByte>
UShort or MUShort extend AbstractUnsigned<Short, Integer, UShort> or AbstractUnsigned<Short, Integer, MUShort>
...etc.
The general idea is to take unsigned upper limit as shifted (casted) type and code transposition of negative values as they were to come not from zero, but the unsigned upper limit.
UPDATE:
(Thanks to Ajeans kind and polite directions)
/**
* Adds value to the current number and returns either
* new or this {#linkplain UnsignedNumber} instance based on
* {#linkplain #isImmutable()}
*
* #param value value to add to the current value
* #return new or same instance
* #see #isImmutable()
*/
public Impl plus(N value) {
return updater(number.plus(convert(value)));
}
This is an externally accessible method of AbstractUnsigned<N, Shifted, Impl> (or as it was said before AbstractUnsigned<Base, Shifted, Impl>);
Now, to the under-the-hood work:
private Impl updater(Shifted invalidated){
if(mutable){
number.setShifted(invalidated);
return caster.apply(this);
} else {
return shiftedConstructor.apply(invalidated);
}
}
In the above private method mutable is a private final boolean of an AbstractUnsigned. number is one of the internal private classes which takes care of transforming Base to Shifted and vice versa.
What matters in correspondence with previous 'what I did last summer part'
is two internal objects: caster and shiftedConstructor:
final private Function<UnsignedNumber<N, Shifted>, Impl> caster;
final private Function<Shifted, Impl> shiftedConstructor;
These are the parameterized functions to cast N (or Base) to Shifted or to create a new Impl instance if current implementation instance of the AbstractUnsigned<> is immutable.
Shifted plus(Shifted value){
return spawnBelowZero.apply(summing.apply(shifted, value));
}
In this fragment is shown the adding method of the number object. The idea was to always use Shifted internally, because it is uncertain when the positive limits of 'original' type will be spawned. shifted is an internal parameterized field which bears the value of the whole AbstractUnsigned<>. The other two Function<> derivative objects are given below:
final private BinaryOperator<Shifted> summing;
final private UnaryOperator<Shifted> spawnBelowZero;
The former performs addition of two Shifted values. And the latter performs spawning below zero transposition.
And now an example from one of the factory boilerplates 'hell' for AbstractUnsigned<Byte, Short> specifically for the mentioned before spawnBelowZero UnaryOperator<Shifted>:
...,
v-> v >= 0
? v
: (short) (Math.abs(Byte.MIN_VALUE) + Byte.MAX_VALUE + 2 + v),
...
if Shifted v is positive nothing really happens and the original value is being returned. Otherwise: there's a need to calculate the upper limit of the Base type which is Byte and add up to that value negative v. If, let's say, v == -8 then Math.abs(Byte.MIN_VALUE) will produce 128 and Byte.MAX_VALUE will produce 127 which gives 255 + 1 to get the original upper limit which was cut of by the sign bit, as I got that, and the so desirable 256 is in the place. But the very first negative value is actually that 256 that's why +1 again or +2 in total. Finally, 255 + 2 + v which is -8 gives 255 + 2 + (-8) and 249
Or in a more visual way:
0 1 2 3 ... 245 246 247 248 249 250 251 252 253 254 255 256
-8 -7 -6 -5 -4 -3 -2 -1
And to finalize all that: this definitely does not ease your work or saves memory bytes, but you have a pretty much desirable behaviour when it is needed. And you can use that behaviour pretty much with any other Number.class subclasses. AbstractUnsigned being subclass of Number.class itself provides all the convenience methods and constants
similar to other 'native' Number.class subclasses, including MIN_VALUE and MAX_VALUE and a lot more, for example, I coded convenience method for mutable subclasses called makeDivisibileBy(Number n) which performs the simplest operation of value - (value % n).
My initial endeavour here was to show that even a noob, such as I am, can code it. My initial endeavour when I was coding that class was to get conveniently versatile tool for constant using.

When casting a small integer type to a wider one, is it safe to rely on &ing with a mask to remove the sign?

I have code that stores values in the range 0..255 in a Java byte to save space in large data collections (10^9 records spread over a couple hundred arrays).
Without additional measures on recovery, the larger values are interpreted as being negative (because the Java integer types use two's complement representation).
I got this helpful hint from starblue in response to a related question, and I'm wondering if this technique is safe to rely on:
int iOriginal = 128, iRestore;
byte bStore = (byte) iOriginal; // reading this value directly would yield -128
iRestore = 0xff & bStore;
Yes, it's safe, indeed it's the most effective way of converting a byte into an (effectively) unsigned integer.
The byte half of the and operation will be sign-extended to an int, i.e. whatever was in bit 7 will be expanded into bits 8-31.
Masking off the bottom eight bits (i.e. & 0xff) then gives you an int that has zero in every bit from 8 - 31, and must therefore be in the range 0 ... 255.
See a related answer I gave here.

Categories