小编Æle*_*lex的帖子

C ++如何为浮点数设置固定的十进制精度

我有一个API调用,它返回一个double。双精度数的十进制长度可以从很多小数位到几个小数位不等(全部归结为执行器的状态)。此双精度表示执行器范围半径上的当前位置。我对这样的详细数字不感兴趣,因为它会给系统增加很多噪音。我一直在使用浮点数来节省空间,但仍然有6-8十进制长度的浮点数。我对地板或天花板不感兴趣,只是因为它不能完成我想要的工作。例如,我有数字:

-2.05176
-0.104545
 0.30643
 0.140237
 1.41205
-0.176715
 0.559462
 0.364928
Run Code Online (Sandbox Code Playgroud)

无论如何,我都希望将精度设置为2个小数位。我不是在谈论std :: cout的输出精度,我知道如何设置它。我说的是浮子的实际精度。即:我对浮点数感兴趣,这些浮点数将具有0.XX格式和0.XX00000000000的实际精度。因此,将上面的列表转换为:

-2.05
-0.10
 0.30
 0.14
 1.41
-0.17
 0.55
 0.36
Run Code Online (Sandbox Code Playgroud)

我知道boost有一个数值转换模板,但是我不知道如何使用较低的精度从float转换为float。有人可以帮忙吗?

c++ boost rounding numeric-conversion

3
推荐指数
1
解决办法
5212
查看次数

C++ boost :: ptr_vector <S> :: iterator问题

我有这门课:

template <class S, class P, class A>
class Task
{
  private:

    timeval start;
    boost::ptr_vector<S> states;
    boost::ptr_vector<P> policies;

  public:

    P findPolicy(S *state);
    S findState(S *state);

};
Run Code Online (Sandbox Code Playgroud)

当我尝试使用迭代器定义findPolicy或findState时:

template <class S, class P, class A>
S Task<S,P,A>::findState(S *state)
{
  boost::ptr_vector<S>::iterator it;
  for ( it = policies.begin(); it < policies.end(); ++it)
  {
    // blah 
  }
}
Run Code Online (Sandbox Code Playgroud)

在类之后定义,编译器说:

error: expected ';' before it;
Run Code Online (Sandbox Code Playgroud)

即使尝试在类声明中定义函数也会给出同样的错误.我很困惑,因为到目前为止我一直在使用boost :: ptr_vector迭代器.似乎唯一有用的东西是老式的:

for (int i = 0; i < policies.size(); i++)
  {
    if (policies[i].getState() == state)
    {
     return policies[i]; …
Run Code Online (Sandbox Code Playgroud)

c++ boost-iterators

3
推荐指数
1
解决办法
265
查看次数

C++如何推广类函数参数来处理多种类型的函数指针?

我不知道我所要求的是可行的,愚蠢的还是简单的.我最近才开始住在模板函数和类中,我想知道下面的场景是否可行:一个包含要调用的函数指针的类.函数指针不能是特定的,而是抽象的,因此无论何时调用类的构造函数,它都可以接受不同类型的函数指针.当调用类的execute函数时,它会使用参数(或参数)执行在构造时分配的函数指针.基本上,抽象在整个设计中保留,并在用户上留下要传递的函数指针和参数.以下代码尚未经过测试,只是为了演示我正在尝试做的事情:

void (*foo)(double);
void (*bar)(double,double);
void (*blah)(float);

class Instruction
{
    protected:
      double var_a;
      double var_b;
      void (*ptr2func)(double);
      void (*ptr2func)(double,double);  
    public:
      template <typename F> Instruction(F arg1, F arg2, F arg3)
      {
         Instruction::ptr2func = &arg1;
         var_a = arg2;
         var_b = arg3;
      };    
      void execute()
      {
         (*ptr2func)(var_a);
      };
};
Run Code Online (Sandbox Code Playgroud)

我不喜欢我必须在可能的可重载函数指针类中保留一个列表的事实.我怎么可能改进上面的内容以尽可能地概括它,以便它可以与任何类型的函数指针一起使用?请记住,我将保留这些实例化对象的容器并按顺序执行每个函数指针.谢谢 !编辑:也许这个类应该是它自己的模板,以便于使用许多不同的函数指针?编辑2:我找到了解决问题的方法,仅供将来参考,不知道它是否正确,但它有效:

class Instruction
{
  protected:
    double arg1,arg2,arg3;
  public:
    virtual void execute() = 0;
};

template <class F> class MoveArm : public Instruction
{
  private:
    F (func);    
  public:
   template <typename T> 
   MoveArm(const T& f,double …
Run Code Online (Sandbox Code Playgroud)

c++ templates pointers abstraction function

2
推荐指数
1
解决办法
2354
查看次数

boost :: random和boost:uniform_real可以使用双倍而不是浮点数吗?

如果已经讨论过,请原谅我.我有一个模板函数,它根据模板参数使用boost :: uniform_int和boost :: uniform_real,并且应该返回相同的类型:

template <typename N> N getRandom(int min, int max)
{
  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed((int)t.tv_sec);
  boost::uniform_int<> dist(min, max);
  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > random(seed, dist);
  return random(); 
}
//! partial specialization for real numbers
template <typename N> N getRandom(N min, N max)
{
  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed( (int)t.tv_sec );
  boost::uniform_real<> dist(min,max);
  boost::variate_generator<boost::mt19937&, boost::uniform_real<> > random(seed,dist);
  return random(); 
}
Run Code Online (Sandbox Code Playgroud)

现在我用int,float和double测试了这个函数.它适用于int,它可以正常使用double,但它不适用于浮点数.就好像它将float转换为int,或者存在一些转换问题.原因我说这是因为当我这样做时:

float y = getRandom<float>(0.0,5.0);
Run Code Online (Sandbox Code Playgroud)

我总是得到一个回归.但是,就像我说的那样,它适用于双打.有什么我做错了或错过了吗?谢谢 !

c++ floating-point boost uniform boost-random

2
推荐指数
3
解决办法
5411
查看次数

C++ linux时间冻结应用程序

我正在导入<sys/time.h>和使用

struct time_t *start;
Run Code Online (Sandbox Code Playgroud)

一个类有一个成员time_t*start; 和一个成员函数getETA():

template <class S, class P> 
double Task<S,P>::getETA()
{ 
  time_t *stop;
  time(stop);
  return difftime(*stop , *start);
}
Run Code Online (Sandbox Code Playgroud)

另请注意,time_t*start在类构造函数中初始化.

每当我调用getETA()时,应用程序就会冻结.更有趣的是,我在主循环中的main.cpp中使用了相同的结构和代码,显然它也冻结了应用程序:

int main(int argc, char **argv) 
{ 
  ...
  time_t *start;
  time(start);
  ...
}
Run Code Online (Sandbox Code Playgroud)

我用错了吗?我记得在很久以前的一些应用中,这就是我如何使用它并且它运行良好.

c++ linux time

2
推荐指数
2
解决办法
324
查看次数

std :: unordered_set允许插入重复项

我不理解正确的事情.我的印象是unordered_set不允许基于哈希的重复元素.

我有一个结构,具有std :: hash的特化,它似乎允许重复,虽然我已经手动检查它

AddEdge ( const std::shared_ptr<Relation> relation, const std::shared_ptr<Concept> concept )
{
    auto edge = std::make_shared<Edge>( (Edge){ relation, concept } );
    auto res = _edges.insert ( edge );
    return res.second;
}
Run Code Online (Sandbox Code Playgroud)

重载函数完全相同但反转参数

这是struct Edge的散列方式:

namespace std
{
    template<> struct hash<shared_ptr<Edge>>
    {
        size_t operator()( const shared_ptr<Edge> & ptr ) const
        {
            size_t from = 0;
            size_t to = 0;

            if ( auto node = std::dynamic_pointer_cast<Concept>( ptr->from ) )
                from = hash<shared_ptr<Concept>>()( node );

            else if ( auto node = …
Run Code Online (Sandbox Code Playgroud)

c++ hash c++11

2
推荐指数
1
解决办法
5802
查看次数

std :: bad_function_call自调用递归lambda但没有提示

我在OSX上使用lldb和llvm(clang 6.0).以下代码在第30行抛出std :: bad_function_call:

std::function<void ( const std::shared_ptr<Node>, unsigned int )> find_next;
find_next = [=]( const std::shared_ptr<Node> node_to, unsigned int len )
{
    for ( const auto rhs : _edges )
    {  
        assert(node_to);
        assert(rhs.from);
        if ( (*node_to) == (*rhs.from) ) 
        {
            len++;
            find_next ( rhs.from, len );   // line 30
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

这是调用者,正好在lambda的定义之下:

for ( const auto lhs : _edges )
{
    unsigned int len = 0;
    const auto from = lhs.to;
    find_next ( from, len );
}
Run Code Online (Sandbox Code Playgroud)

这是lldb输出: …

c++ recursion lambda c++11

2
推荐指数
1
解决办法
934
查看次数

改变不区分大小写的字符串比较性能

所以,我的博士项目依赖于我已经建立了近3年的软件.它运行,它稳定(它没有崩溃或抛出异常),我正在玩它的发布版本.而且我已经意识到有巨大的性能损失,因为我过分依赖boost :: iequals.我知道,关于这一点有很多关于这个的问题,这不是关于如何做到这一点的问题,而是为什么会发生这种情况.考虑以下:

#include <string.h>
#include <string>
#include <boost/algorithm/string.hpp>

void posix_str ( )
{
    std::string s1 = "Alexander";
    std::string s2 = "Pericles";
    std::cout << "POSIX strcasecmp: " << strcasecmp( s1.c_str(), s2.c_str() ) << std::endl;
}

void boost_str ( )
{
    std::string s1 = "Alexander";
    std::string s2 = "Pericles";
    std::cout << "boost::iequals: " << boost::iequals( s1, s2 ) << std::endl;
}

int main ( )
{
    posix_str();
    boost_str();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我把它放在valgrind和cachegrind中,令我惊讶的是,boost比原生posix或std(看起来使用相同的posix)方法慢4倍.四次,现在已经很多了,即使考虑到C++提供了一个很好的安全网.这是为什么?我真的希望其他人能够运行这个,并向我解释一下这样的性能如何受到影响.是所有的分配(似乎来自呼叫者地图).我并不喜欢提升,我喜欢它并随处随地使用它.编辑:此图显示了我的意思

c++ string boost c++11

2
推荐指数
1
解决办法
884
查看次数

std :: function参数是不允许的不完整类型

我正在尝试将lambda分配给a std::function,如下所示:

std::function<void>(thrust::device_vector<float>&) f;
f = [](thrust::device_vector<float> & veh)->void
{   
    thrust::transform( veh.begin(), veh.end(), veh.begin(), tanh_f() );
};
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

 error: incomplete type is not allowed
 error: type name is not allowed
Run Code Online (Sandbox Code Playgroud)

我认为它指的是thrust::device_vector<float>.我尝试了typenaming和typedefining参数:

typedef typename thrust::device_vector<float> vector;
std::function<void>(vector&) f;
f = [](vector & veh)->void
{   
    thrust::transform( veh.begin(), veh.end(), veh.begin(), tanh_f() );
};
Run Code Online (Sandbox Code Playgroud)

无济于事.但是,如果我只使用lambda(没有std::function)它可以工作:

typedef typename thrust::device_vector<float> vector;
auto f = [](vector & veh)->void
{   
    thrust::transform( veh.begin(), veh.end(), veh.begin(), tanh_f() );
};
Run Code Online (Sandbox Code Playgroud)

我错过了什么?PS:我正在编译使用nvcc release 6.5, V6.5.12和 …

c++ lambda c++11

2
推荐指数
1
解决办法
1732
查看次数

std ::从向量的位置复制到向量的位置

这可能是我非常疲惫,但我无法弄清楚如何将一部分矢量复制到一个新的矢量.

我想要做的是,在std :: vector(其中char是typedefed as byte)中找到起始标记,并从那里复制数据,直到结束标记(最后是,并且是7个字符长).

typedef char byte;
std::vector<byte> imagebytes;
std::vector<byte> bytearray_;

for ( unsigned int i = 0; i < bytearray_.size(); i++ )
{
    if ( (i + 5) < (bytearray_.size()-7) )
    {
        std::string temp ( &bytearray_[i], 5 );

        if ( temp == "<IMG>" )
        {
            // This is what isn't working
            std::copy( std::vector<byte>::iterator( bytearray_.begin() + i + 5 ),
                       std::vector<byte>::iterator( bytearray_.end() - 7 )
                       std::back_inserter( imagebytes) );
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

我知道这个循环看起来很可怕,我愿意接受建议!请注意,bytearray_包含图像的原始字节或音频文件.因此矢量.

c++ vector c++11

1
推荐指数
1
解决办法
784
查看次数