我有一个数字存储为 ulong。我希望存储在内存中的位以 2 的补码方式解释。所以我希望第一位是符号位等。如果我想转换为 long,以便该数字被正确解释为 2 的补码,我该怎么做?
我尝试创建不同数据类型的指针,它们都指向同一缓冲区。然后我将 ulong 存储到缓冲区中。然后我取消引用一个长指针。但这给了我一个不好的结果?
我做到了:
#include <iostream>
using namespace std;
int main() {
unsigned char converter_buffer[4];//
unsigned long *pulong;
long *plong;
pulong = (unsigned long*)&converter_buffer;
plong = (long*)&converter_buffer;
unsigned long ulong_num = 65535; // this has a 1 as the first bit
*pulong = ulong_num;
std:: cout << "the number as a long is" << *plong << std::endl;
return 0;
}
出于某种原因,这给了我相同的正数。 选角会有帮助吗?
最佳答案
实际上使用指针是一个好的开始,但您必须先将 unsigned long*
转换为 void*
,然后才能将结果转换为 long*
并取消引用它:
#include <iostream>
#include <climits>
int main() {
unsigned long ulongValue = ULONG_MAX;
long longValue = *((long*)((void*)&ulongValue));
std::cout << "ulongValue: " << ulongValue << std::endl;
std::cout << "longValue: " << longValue << std::endl;
return 0;
}
上面的代码将产生以下结果:
ulongValue: 18446744073709551615
longValue: -1
使用模板,您可以使其在代码中更具可读性:
#include <iostream>
#include <climits>
template<typename T, typename U>
T unsafe_cast(const U& from) {
return *((T*)((void*)&from));
}
int main() {
unsigned long ulongValue = ULONG_MAX;
long longValue = unsafe_cast<long>(ulongValue);
std::cout << "ulongValue: " << ulongValue << std::endl;
std::cout << "longValue: " << longValue << std::endl;
return 0;
}
请记住,此解决方案绝对不安全,因为您可以将任何内容转换为 void*
。这种做法在 C 中很常见,但我不建议在 C++ 中使用它。考虑以下情况:
#include <iostream>
template<typename T, typename U>
T unsafe_cast(const U& from) {
return *((T*)((void*)&from));
}
int main() {
std::cout << std::hex << std::showbase;
float fValue = 3.14;
int iValue = unsafe_cast<int>(fValue); // OK, they have same size.
std::cout << "Hexadecimal representation of " << fValue
<< " is: " << iValue << std::endl;
std::cout << "Converting back to float results: "
<< unsafe_cast<float>(iValue) << std::endl;
double dValue = 3.1415926535;
int lossyValue = unsafe_cast<int>(dValue); // Bad, they have different size.
std::cout << "Lossy hexadecimal representation of " << dValue
<< " is: " << lossyValue << std::endl;
std::cout << "Converting back to double results: "
<< unsafe_cast<double>(lossyValue) << std::endl;
return 0;
}
上面的代码对我来说结果如下:
Hexadecimal representation of 3.14 is: 0x4048f5c3
Converting back to float results: 3.14
Lossy hexadecimal representation of 3.14159 is: 0x54411744
Converting back to double results: 6.98387e-315
最后一行你可以获得任何东西,因为转换将从内存中读取垃圾。
编辑
如lorro下面评论说,使用memcpy()更安全,可以防止溢出。因此,这是类型转换的另一个版本,它更安全:
template<typename T, typename U>
T safer_cast(const U& from) {
T to;
memcpy(&to, &from, (sizeof(T) > sizeof(U) ? sizeof(U) : sizeof(T)));
return to;
}
关于c++ - 将 ulong 转换为 long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43526910/