Java Bitshift错误,为负数
Java Bitshift error with negatives?
http://www.fastcgi.com/devkit/doc/fcgi-spec.html第3.4节:
typedef struct {
unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */
unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */
unsigned char nameData[nameLength];
unsigned char valueData[valueLength];
} FCGI_NameValuePair11;
typedef struct {
unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */
unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */
unsigned char valueLengthB2;
unsigned char valueLengthB1;
unsigned char valueLengthB0;
unsigned char nameData[nameLength];
unsigned char valueData[valueLength
((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
} FCGI_NameValuePair14;
typedef struct {
unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */
unsigned char nameLengthB2;
unsigned char nameLengthB1;
unsigned char nameLengthB0;
unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */
unsigned char nameData[nameLength
((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
unsigned char valueData[valueLength];
} FCGI_NameValuePair41;
typedef struct {
unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */
unsigned char nameLengthB2;
unsigned char nameLengthB1;
unsigned char nameLengthB0;
unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */
unsigned char valueLengthB2;
unsigned char valueLengthB1;
unsigned char valueLengthB0;
unsigned char nameData[nameLength
((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
unsigned char valueData[valueLength
((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
} FCGI_NameValuePair44;
我正在Java中实现这一点,为了完成valueLengthB3 >> 7 == 1
等部分,我只是将其设置为负数。这行不通。否定在Java中是如何工作的,在Java中如何执行此操作?
我当前的代码:
public void param(String name, String value) throws IOException {
if (fp) {
throw new IOException("Params are already finished!");
}
if (name.length() < 128) {
dpout.write(name.length());
}else {
dpout.writeInt(-name.length());
}
if (value.length() < 128) {
dpout.write(value.length());
}else {
dpout.writeInt(-value.length());
}
dpout.write(name.getBytes());
dpout.write(value.getBytes());
}
Java使用非常常规的整数运算。与C和C++相关的两个主要特性是
- Java除了
char
(16位宽)之外没有其他无符号整数类型,并且 - Java有单独的算术(
>>
)和逻辑(>>>
)右移运算符。前者通过用左操作数最高有效位的副本填充结果所需的最高有效位来保留符号,而后者用零填充结果的最高有效位数
Java的优点是,所有基元类型在所有平台上都具有众所周知的、一致的大小和签名性,并且它的两个右移运算符对所有有效操作数都具有定义良好的语义。相反,在C中,对负值执行右移的结果是实现定义的,所有的标准数据类型都具有实现定义的大小,并且一些类型(char
)具有实现定义签名性。
然而,既然您已经发布了一些代码,那么这些似乎都不是您的问题。我不明白为什么你认为否定一个数字会进行任何形式的转换,或者实际上,为什么你认为你想要做的事情需要转换。
特别要注意的是,Java使用2的补码整数表示法(这也是C编译器最常见的选择),因此否定一个数字所修改的不仅仅是符号位。如果你只想设置int
的符号位,那么你可以拼写
value.length() | 0x80000000
如果您通过导线接收byte
,它们将被签名,这意味着最高有效位将是符号位。如果你想从byte
中提取符号位,你会想到两种合理的方法:通过与0
进行比较来测试负性,或者使用>>>
运算符,而不是>>
运算符。
下面的代码显示了我如何在C中取消对signed char
s的数组的序列化。我无法想象为什么这在Java中不起作用,假设data
是byte
s的数组……尽管我确信这会很可怕。
long offset = 0;
long nameLength = data[offset] >= 0 ? data[offset++] : (-(long)data[offset++] << 24)
+ ( (long)data[offset++] << 16)
+ ( (long)data[offset++] << 8)
+ data[offset++];
long valueLength = data[offset] >= 0 ? data[offset++] : (-(long)data[offset++] << 24)
+ ( (long)data[offset++] << 16)
+ ( (long)data[offset++] << 8)
+ data[offset++];
for (long x = 0; x < nameLength; x++) {
/* XXX: Copy data[offset++] into name */
}
for (long x = 0; x < valueLength; x++) {
/* XXX: Copy data[offset++] into value */
}
相关文章:
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- Java Bitshift错误,为负数