我正在尝试从16个元素的字节数组中获取数字(double)值,如下所示:
unsigned char input[16];
double output;
...
double a = input[0];
distance = a;
for (i=1;i<16;i++){
a = input[i] << 8*i;
output += a;
}
但它不起作用。 似乎包含左移结果的临时变量只能存储32位,因为在8位的4位移位操作之后它会溢出。
我知道我可以使用像
这样的东西a = input[i] * pow(2,8*i);
但是,出于好奇,我想知道使用移位运算符是否有任何解决方案...
答案 0 :(得分:4)
编辑:如果没有像__int128
这样的内容,这将无效(请参阅评论)。
a = input[i] << 8*i;
表达式input[i]
被提升为int
(6.3.1.1),在您的计算机上为32位。要解决这个问题,左手操作数必须是64位,如
a = (1L * input[i]) << 8*i;
或
a = (long long unsigned) input[i] << 8*i;
并记住关于字节序的内容
答案 1 :(得分:4)
这里的问题是32位变量确实不能移动超过4 * 8次,即你的代码仅适用于4个字符。
你能做的是找到第一个重要的字符,并使用霍纳定律: n x n + a n-1 < sup> n-1 + ... =((...( n x + a n-1 )。x + a n-2 )。x + ...)+ a 0 如下:
char coefficients[16] = { 0, 0, ..., 14, 15 };
int exponent=15;
double result = 0.;
for(int exponent = 15; exp >= 0; --exp ) {
result *= 256.; // instead of <<8.
result += coefficients[ exponent ];
}
答案 2 :(得分:2)
简而言之,不,您无法通过代码示例所示的位移将byte
s序列直接转换为double
。
byte
,整数类型和double
,浮点类型(即不是整数类型)不是按位兼容的(即你不能只是将一串字节的值转换为浮点类型并期望得到相同的结果。)
1)假设字节数组是引用整数值的内存缓冲区,您应该能够通过位移将byte
数组转换为128位整数,然后将得到的整数转换为{ {1}}。不要忘记,端口问题可能会起作用,具体取决于CPU架构。
2)假设字节数组是一个包含128位长双精度值的内存缓冲区,并假设没有字节序问题,那么你应该能够将字节数组中的值memcpy为long double值
double
答案 3 :(得分:2)
为什么不简单地将数组转换为双指针?
unsigned char input[16];
double* pd = (double*)input;
for (int i=0; i<sizeof(input)/sizeof(double); ++i)
cout << pd[i];
如果需要修复endian-ness,请在转换为double数组之前使用STL reverse()反转char数组。
答案 4 :(得分:1)
您是否尝试过std :: atof:
答案 5 :(得分:1)
您是否尝试将数字的字符串表示形式转换为实数?在这种情况下,C标准atof是你最好的朋友。
答案 6 :(得分:0)
基于运算符优先级
的右侧a = input[i] << 8*i;
在转换为double之前进行求值,因此您将input [i]移位8 * i位,将其结果存储在32位临时变量中,从而溢出。您可以尝试以下方法:
a = (long long unsigned int)input[i] << 8*i;
编辑:不确定您的系统上的双倍大小是什么,但在我的系统上它是8个字节,如果是这种情况,那么输入数组的后半部分将是永远不会被看到,即使是双重类型也会溢出。