Search code examples
c++eigen

Eigen c++ cast double to long int?


Quick question:

consider this (wrong) casting from a double to a long int:

Eigen::VectorXd Price      = Map<VectorXd>(price, n);
double TickFactor          = 1.0 / TickSize;
Eigen::VectorXi IntPrice   = (Price * TickFactor).cast <long int> ();

which gives the following error (Eigen 3.3.5, g++ 7.3.0):

eigen/Eigen/src/Core/util/StaticAssert.h:33:40: error: static assertion failed: YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY
     #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);

Now, this compiles:

Eigen::VectorXi IntPrice   = (Price * TickFactor).cast <int> ();

here is my question. Does the line above allows for values of (Price * TickFactor) that are larger than the upper limit on a short int? --whatever that is on the current system, say 33K.


Solution

  • This line

    Eigen::VectorXi IntPrice   = (Price * TickFactor).cast <int> ();
    

    is essentially equivalent to

    Eigen::VectorXi IntPrice(Price.size());
    for(Eigen::Index i=0; i<Price.size(); ++i)
        IntPrice[i] = static_cast<int>(Price[i] * TickFactor;
    

    Unless on your system short int and int are the same, you are limited to the size of int (not short int), and the behavior for overflows is (I think) undefined.

    If you want 64bit integers, do as ggael suggested:

    typedef Eigen::Matrix<int64_t,Dynamic,1> VectorXi64;
    
    VectorXi64 IntPrice = (Price * TickFactor).cast<int64_t>();