将 Big Endian 格式位转换为预期的十进制值,同时忽略第一位
Convering Big Endian Formatted Bits to Intended Decimal Value While Ignoring First Bit
我正在读取二进制文件并尝试将 IBM 4 字节浮点数转换为 C++ 中的双精度数。如何使用 IBM 数据的第一个字节在给定图片中找到 ccccccc
IBM to value conversion chart
下面的代码给出了一个比数据应该有的更大的指数。我对
行的方式感到困惑
exponent = ((IBM4ByteValue[0] & 127) - 64);
执行,我不明白这个语句中&运算符的用法。但本质上,这段代码的前任作者暗示的是 (IBM4ByteValue[0]) 是 ccccccc ,那么这是否意味着 & 符号设置了运算符左侧可以等于的最大值?即使这是正确的,但我确定这一行如何解释第一个字节中存在 Big Endian 按位表示法的事实(我相信在查看图片后它是 Big Endian)。更不用说 1000001 和 0000001 应该具有相同的指数 (-63) 但是它们不会符合我当前对前面提到的行的解释。
简而言之,有人可以告诉我如何使用第一个字节 --> IBM4ByteValue[0] 找到 ccccccc(如上图 link 所示)。也许访问每个单独的位?但是我不知道使用我的数组执行此操作的代码。
**此代码正在使用 std 命名空间
**我相信 ret 应该是 mantissa * pow(16, 24+exponent) 但是如果我对指数有误我可能是错的(我从之前问过的 Whosebug 问题中得到了 IBM Conversion)**我会刚刚对旧 post 发表了评论,但这个问题有点太大,双关语,不适合发表评论。它的不同之处还在于我问的是如何访问存储整个字节的数组中的位。
我使用上一个问题答案的 IBM 转换组合在一起的代码
for (long pos = 0; pos < fileLength; pos += BUF_LEN) {
file.seekg(bytePosition);
file.read((char *)(&IBM4ByteValue[0]), BUF_LEN);
bytePosition += 4;
printf("\n%8ld: ", pos);
//IBM Conversion
double ret = 0;
uint32_t mantissa = 0;
uint16_t exponent = 0;
mantissa = (IBM4ByteValue[3] << 16) | (IBM4ByteValue[2] << 8)|IBM4ByteValue[1];
exponent = ((IBM4ByteValue[0] & 127) - 64);
ret = mantissa * exp2(-24 + 4 * exponent);
if (IBM4ByteValue[0] & 128) ret *= -1.;
printf(":%24f", ret);
printf("\n");
system("PAUSE");
}
& 运算符基本上取数组的那个值中的位,并用二进制值 127 对其进行掩码。如果数组值中的某个位为 1,而 127 对应的位位置为 1,该位将是结果 1。1 & 0 将是 0,0 & 0 和 0 & 1 也是如此。您将更改这些位。然后你会得到结果位值,现在转换为十进制,并从中减去 64 等于你的指数。
在浮点数中,指数总是有偏差(在本例中为 64)。这意味着如果您的指数为 5,则将存储 69。所以这段代码试图做的是找到指数的原始值。
我正在读取二进制文件并尝试将 IBM 4 字节浮点数转换为 C++ 中的双精度数。如何使用 IBM 数据的第一个字节在给定图片中找到 ccccccc
IBM to value conversion chart
下面的代码给出了一个比数据应该有的更大的指数。我对
行的方式感到困惑exponent = ((IBM4ByteValue[0] & 127) - 64);
执行,我不明白这个语句中&运算符的用法。但本质上,这段代码的前任作者暗示的是 (IBM4ByteValue[0]) 是 ccccccc ,那么这是否意味着 & 符号设置了运算符左侧可以等于的最大值?即使这是正确的,但我确定这一行如何解释第一个字节中存在 Big Endian 按位表示法的事实(我相信在查看图片后它是 Big Endian)。更不用说 1000001 和 0000001 应该具有相同的指数 (-63) 但是它们不会符合我当前对前面提到的行的解释。
简而言之,有人可以告诉我如何使用第一个字节 --> IBM4ByteValue[0] 找到 ccccccc(如上图 link 所示)。也许访问每个单独的位?但是我不知道使用我的数组执行此操作的代码。
**此代码正在使用 std 命名空间 **我相信 ret 应该是 mantissa * pow(16, 24+exponent) 但是如果我对指数有误我可能是错的(我从之前问过的 Whosebug 问题中得到了 IBM Conversion)**我会刚刚对旧 post 发表了评论,但这个问题有点太大,双关语,不适合发表评论。它的不同之处还在于我问的是如何访问存储整个字节的数组中的位。
我使用上一个问题答案的 IBM 转换组合在一起的代码
for (long pos = 0; pos < fileLength; pos += BUF_LEN) {
file.seekg(bytePosition);
file.read((char *)(&IBM4ByteValue[0]), BUF_LEN);
bytePosition += 4;
printf("\n%8ld: ", pos);
//IBM Conversion
double ret = 0;
uint32_t mantissa = 0;
uint16_t exponent = 0;
mantissa = (IBM4ByteValue[3] << 16) | (IBM4ByteValue[2] << 8)|IBM4ByteValue[1];
exponent = ((IBM4ByteValue[0] & 127) - 64);
ret = mantissa * exp2(-24 + 4 * exponent);
if (IBM4ByteValue[0] & 128) ret *= -1.;
printf(":%24f", ret);
printf("\n");
system("PAUSE");
}
& 运算符基本上取数组的那个值中的位,并用二进制值 127 对其进行掩码。如果数组值中的某个位为 1,而 127 对应的位位置为 1,该位将是结果 1。1 & 0 将是 0,0 & 0 和 0 & 1 也是如此。您将更改这些位。然后你会得到结果位值,现在转换为十进制,并从中减去 64 等于你的指数。
在浮点数中,指数总是有偏差(在本例中为 64)。这意味着如果您的指数为 5,则将存储 69。所以这段代码试图做的是找到指数的原始值。