如何将NumPy的y.view(dtype=int64)*(2**-18)操作转为C++实现?
C++实现NumPy的
y.view(dtype=int64) * (2**-18)操作 需求说明
原NumPy操作的核心逻辑:
- 输入数组
y的每个元素是16个uint8_t值(共128位) - 通过
view(dtype=int64)将这16个uint8_t拆分为2个int64整数(每8个连续uint8_t拼接成一个int64) - 每个int64值乘以
2^-18(即1.0 / 262144.0),得到最终浮点结果
输入示例
[0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0], [0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0], [209 97 173 255 255 255 255 255 157 210 83 0 0 0 0 0], [ 99 139 170 255 255 255 255 255 4 214 86 0 0 0 0 0], [ 46 172 247 255 255 255 255 255 225 125 8 0 0 0 0 0], [178 109 184 255 255 255 255 255 223 166 72 0 0 0 0 0], [0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0], [0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0]
预期输出示例
y_fpga: [[ 1. 0. ] [ 1. 0. ] [-20.65447617 20.95567703] [-21.36388016 21.70899963] [ -2.08185577 2.12292862] [-17.89287567 18.16296005] [ 1. 0. ] [ 1. 0. ]]
C++实现方案
核心步骤
- 处理字节序:默认按x86平台的小端序拼接字节(NumPy
view操作遵循系统原生字节序),大端序需调整拼接逻辑 - 拆分每组16个uint8_t为两组8个字节,分别拼接成int64_t整数
- 将int64_t转换为double类型,乘以缩放因子
2^-18得到结果
代码实现
#include <iostream> #include <vector> #include <cstdint> #include <iomanip> // 小端序:8个uint8_t拼接为int64_t int64_t uint8_to_int64_le(const uint8_t* bytes) { int64_t result = 0; for (int i = 0; i < 8; ++i) { result |= static_cast<int64_t>(bytes[i]) << (i * 8); } return result; } // 大端序:8个uint8_t拼接为int64_t(按需切换) // int64_t uint8_to_int64_be(const uint8_t* bytes) { // int64_t result = 0; // for (int i = 0; i < 8; ++i) { // result |= static_cast<int64_t>(bytes[7 - i]) << (i * 8); // } // return result; // } int main() { // 输入数据:8组,每组16个uint8_t std::vector<std::vector<uint8_t>> input = { {0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {209, 97, 173, 255, 255, 255, 255, 255, 157, 210, 83, 0, 0, 0, 0, 0}, {99, 139, 170, 255, 255, 255, 255, 255, 4, 214, 86, 0, 0, 0, 0, 0}, {46, 172, 247, 255, 255, 255, 255, 255, 225, 125, 8, 0, 0, 0, 0, 0}, {178, 109, 184, 255, 255, 255, 255, 255, 223, 166, 72, 0, 0, 0, 0, 0}, {0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; const double scale_factor = 1.0 / (1 << 18); // 2^-18 = 1/262144 std::cout << "y_fpga: [" << std::endl; for (const auto& vec : input) { // 拆分前8字节和后8字节,转换为int64_t int64_t val1 = uint8_to_int64_le(vec.data()); int64_t val2 = uint8_to_int64_le(vec.data() + 8); // 计算浮点结果 double res1 = static_cast<double>(val1) * scale_factor; double res2 = static_cast<double>(val2) * scale_factor; // 格式化输出,匹配示例精度 std::cout << " [" << std::setw(12) << std::fixed << std::setprecision(8) << res1 << " " << std::setw(12) << std::fixed << std::setprecision(8) << res2 << "]" << std::endl; } std::cout << "]" << std::endl; return 0; }
补充说明
- 若运行环境为大端序,可注释掉小端序函数,启用大端序版本的
uint8_to_int64_be - 代码使用
std::fixed和std::setprecision(8)控制输出精度,与示例对齐 - 输入数据结构可根据实际场景替换为C风格数组或其他容器
内容的提问来源于stack exchange,提问作者akshay malige
相关产品推荐
相关产品推荐

