Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将二进制文件中的复数值读入STL向量_C++ - Fatal编程技术网

C++ 将二进制文件中的复数值读入STL向量

C++ 将二进制文件中的复数值读入STL向量,c++,C++,我有一个已知数量的复远场电场值的二进制文件,它与频率有关。每个条目两个浮点值(32位),其中第一个浮点值是实部,第二个浮点值是虚部)。因此,文件大小为2*4*(频率数) 根据C++11标准,std::vector和std::complex必须在内存中连续(一个字可能太强?)。对于复值向量,这是真的吗 是否可以使用std::ifstreamread函数将上述二进制文件中的这些复杂值直接加载到预先分配的STL(std::vector)中的底层动态数组中 我应该补充的是,这些文件可以在GB范围内。分配

我有一个已知数量的复远场电场值的二进制文件,它与频率有关。每个条目两个浮点值(32位),其中第一个浮点值是实部,第二个浮点值是虚部)。因此,文件大小为2*4*(频率数)

  • 根据C++11标准,
    std::vector
    std::complex
    必须在内存中连续(一个字可能太强?)。对于复值向量,这是真的吗

  • 是否可以使用
    std::ifstream
    read函数将上述二进制文件中的这些复杂值直接加载到预先分配的STL(
    std::vector
    )中的底层动态数组中


  • 我应该补充的是,这些文件可以在GB范围内。分配一个固定或动态的
    浮点数组,读入,然后复制到
    std::vector
    中是不切实际的。如果你想走这条路,你需要以下结构:

  • ifstream::read(&vec[0],nFreq*sizeof(complex))

  • 对于预分配内存上的
    std::complex
    构造

  • vec;
    向量储备(nFreq);//如果由于文件太大而导致分配失败,请记住捕获异常

  • 为了进一步“证明”(无法访问标准)您的位置和文件内容的有效性,a:

    对于任何复数z,
    重新解释_cast(z)[0]是z和
    (z)[1]是z的虚部。
    对于指向复数数组p和p元素的任何指针
    任何有效的数组索引i,
    重新解释_cast(p)[2*i]是复数p[i]的实部,并且
    重新解释_cast(p)[2*i+1]是复数p[i]的虚部
    
    这些要求本质上限制了std::complex三个专门化的实现,即声明两个且仅两个类型为value_type的非静态数据成员,具有相同的成员访问权限,分别包含实部和虚部


    这是可能的,我认为-使用复杂的专门化,并在预大小的向量桶上使用placement new进行覆盖。如果您非常关心性能,请计算文件中有多少条目,然后分配一个固定大小的数组并将其直接读取到其中。您必须先使用
    调整大小
    ,这不是免费的。相比于说
    emplace\u back
    你不会获得多少性能,我可能只会使用
    mmap
    reinterpret\u cast(…)
    。那样的话,零开销。或者更好的方法是,除非你真的必须,否则不要同时将整个数据加载到内存中。优化在任何语言中都可以归结为相同的概念-最小化磁盘I/O(一次读取所有数据),使下一次使用的数据尽可能接近cpu寄存器(缓存->ram->磁盘)。你的方法是正确的,但是@MooingDuck的技术比你建议的要快得多。与往常一样,越优化,您的便利性就越少(失去向量功能)。然而,也许你想看看matlab中的MEX编译器?编译成c,然后手工优化剩下的是什么?我想说,没有必要重新发明轮子。你能再解释一下placement new的相关性和用途吗?初学者。@我确信你知道,SnaKeYeS1482.调用C++中的对象的构造函数为堆上的内存分配(使用new)。它不能保证内存在哪里。使用placement new,您可以准确地告诉它要使用的内存块,因为在您的情况下,您已经为它做好了准备。不过,我还是要先研究一下MEX如何编译您的MATLAB代码。他们这样做基本上就是为了这个原因
    For any complex number z, 
    reinterpret_cast<T(&)[2]>(z)[0] is the real part of z and 
    reinterpret_cast<T(&)[2]>(z)[1] is the imaginary part of z.
    
    For any pointer to an element of an array of complex numbers p and
    any valid array index i, 
    reinterpret_cast<T*>(p)[2*i] is the real part of the complex number p[i], and
    reinterpret_cast<T*>(p)[2*i + 1] is the imaginary part of the complex number p[i]