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());
}

#1楼 票数:1 已采纳

Java使用漂亮的常规整数运算。 关于C和C ++的两个主要特点是

  1. Java除了char (16位宽)外没有其他无符号整数类型,并且
  2. Java具有单独的算术( >> )和逻辑( >>> )右移运算符。 前者通过用左操作数的最高有效位的副本填充结果的所需最高有效位来保留符号,而后者则用零填充结果的最高有效位。

Java的优势在于,所有原始类型在所有平台上均具有众所周知的一致大小和符号,并且它的两个右移运算符对所有有效操作数具有明确定义的语义。 相反,在C中,对负值执行右移的结果是实现定义的, 所有标准数据类型都具有实现定义的大小,而某些类型( char )具有实现定义的符号。

但是,既然您已经发布了一些代码,看来所有这些实际上都不是您的问题。 我不知所措,您为什么会认为否定数字会进行任何形式的转换,或者实际上,为什么您认为您要进行的操作根本需要进行转换。

特别要注意的是,Java使用二进制补码表示形式(这也是迄今为止C编译器的最常见选择),因此,数字取反的含义不只是符号位。 相反,如果您只想设置int的符号位,则可以将其拼写为

value.length() | 0x80000000

#2楼 票数:0

如果您要通过电线接收byte s,则将对它们进行签名,这意味着最高有效位将是符号位。 如果要从byte提取符号位,则有两种明智的方法:通过与0比较或使用>>>运算符而不是>>运算符来测试负性。

下面的代码显示了我如何在C中反序列化这样一个带signed char数组。我无法想象为什么在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 */
}

  ask by JavaProphet translate from so

未解决问题?本站智能推荐:

4回复

在Java或C中对字符进行位操作?

我是一名学生,正在尝试实施DES算法。 我可以选择2种语言:C和Java。 我确实理解了这个算法,但是在操作密钥时一开始就陷入困境。 这是问题所在。 在DES中,我们有一个64位密钥(C中有8个字符,Java中有4个字符,但我可以将字符串转换为字节以仅获取ASCII部分),其中每8位
8回复

n是负数,正数还是零? 返回1、2或4

我正在构建PowerPC解释器,并且效果很好。 在Power架构中,条件寄存器CR0(x86上的EFLAGS)几乎在任何指令上都会更新。 这样设置。 如果最后一个结果为负,则CR0的值为1,如果最后一个结果为正,则CR0的值为2,否则为4。 我的第一个天真的解释方法是: 但是
8回复

负数如何存储在内存中? 如何知道位表示?

我知道MSB,LSB,符号和幅度的一,二的补码等。现在,我想知道我是否正在编写和编程进行某些位操作的代码,如何检查内存中的实际位级别数据? 即int a = -1; 我怎么知道4位表示是1001还是1110或1111 ? 如何找出实现中用于表示负数的方法? 我正在寻找某种方法
2回复

按负数移位

我对这里的表达很困惑。 我是一名Java程序员,但我并不精通位操作。 我想我理解正确如下: 对于正数,我认为你是1乘10位。 混淆是我有以下情况: 如果有人可以通过负数向我解释左移或右移的含义,那将是非常好的。
4回复

带有警告的饱和算术问题

我必须创建两个将无符号/有符号数字加在一起的函数。 但是,编译器向我发出以下警告,并且实现似乎无法正确运行(因为它停滞了)。 我相信这里可能存在逻辑错误,而不是语义上的其他错误,这使我不满意。 我对此并不陌生,不胜感激。 警告: 由于数据类型范围有限,比较始终为假; //
1回复

在按位和在 c 上的 unsigned int 上得到错误的答案? [关闭]

关闭。 这个问题需要调试细节。 它目前不接受答案。 想改善
7回复

Java中按位与(AND)如何工作?

我正在阅读一些代码示例,并在Oracle网站的Bitwise和Bit Shift Operators页面上遇到了& 。 在我看来,解释按位&的工作效果不佳。 我知道它直接执行操作,但是我不确定该执行哪种操作,并且我想知道该操作是什么。 这是我从Oracle网站获得的示例程序
3回复

Java中的128位表示形式和原语

我需要在Java中表示128位int密钥,例如 0x9c1f03a0d9cf510f2765bd0f226ff5dc 我知道理论上如何表示128位变量。切成2个64位int或四个32位int。 但是我需要比较键(k1 <k2和k1 == k2)的这种表示形式,而且我不知道