【导读】
java中没有unsigned,将c/c++代码转换为java代码时,会遇到类型不匹配的问题。笔者在做过一次c/c++加密代码转换为java代码后,将其中的类型转换技巧整理出来,以便和大家分享。
【正文】
1. java和c++的数据类型
c++ | java | 字节数 |
signed char | byte | 1 |
signed short | char/short | 2 |
signed int/long | int | 4 |
signed long long | long | 8 |
float | float | 4 |
double | double | 8 |
boolean | bool | 1 |
2. java中模拟unsigned
(1). 类型的确定:
java类型没有signed,所以要模拟c++中的unsigned,就要用当前类型更高一级的类型才能容纳unsigned所有的值。
例如:c++ unsigned char的取值范围 [0-255], 占1个字节。而java中byte取值是[-128, 127], 也占一个字节,但是byte类型表示不了[128-255]之间的值。
所以得用更高一级的short来模拟。
(2).取值范围的确定
例如:java中short的取值范围在[-32768-32767],能覆盖c++中unsigned char的[0-255],而且还多出来了。所以如果能保证java中short的变量值在[0-255]之间,short变量的取值和unsigned char的取值就一样了。
基于这个思路,我们可以实现unsigned的模拟。
3. java代码的的实现
(1) . 模拟c++中unsigned char
// unsigned char
static public short add(short a, short b) {
return (short)((java_short_to_unsigned_char(a) + java_short_to_unsigned_char(b)) % 256);
}
static public short java_short_to_unsigned_char(short a) {
return (short)(((byte)a + 256) % 256);
}
(2).模拟c++中unsigned short
// unsigned short
static public int add(int a, int b) {
return (java_int_to_cpp_unsigned_short(a) + java_int_to_cpp_unsigned_short(b)) % 65536;
}
static public int java_int_to_cpp_unsigned_short(int a) {
return ((short)a + 65536) % 65536;
}
(3). 模拟c++中unsigned int或者unsigned long
// unsigned long
static public long add(long a, long b) {
return (java_long_to_cpp_unsigned_long(a) + java_long_to_cpp_unsigned_long(b)) % 4294967296L;
}
static public long java_long_to_cpp_unsigned_long(long a) {
return ((int)a + 4294967296L) % 4294967296L;
}
4. 注意点:
java中当用更高一级的数据类型来模拟c++中unsigned, 一定要保证数据操作在unsigned的取值范围内,尤其是多个数据连续操作(比如相加),每一步的操作结果都在unsigned范围内,否则会出错。
比如:
long a = 0x55555555;
long b = 0x66666666;
long c = 0x77777777;
long sum = add(add(a, b), c);
System.out.println(sum); // ok
System.out.println(java_long_to_cpp_unsigned_long(a + b + c)); // ok
【总结】
从二进制的角度看,虽然java中没有unsigned,但是依然可以实现。