dimanche 1 octobre 2017

Adding very small and very large floating point numbers [duplicate]

This question already has an answer here:

I noticed something in my visual studio (2017) and was hoping to get some help.

I have a very small representation of a second (nanoseconds, 1.0e-9) but also a large representation of seconds (>3e10) that have passed, but when adding the two numbers together the nanoseconds disappears or is wrong.

For example:

double nanosecond = 1.0e-9;
double seconds_in_year = 31536000.0;
double result = seconds_in_year + nanosecond;

What I get for result is seconds_in_year, with no 1.0e-9. If I change nanosecond to ~5.0e-9, I get 31536000.000000004, which is off by one nanosecond.

It seems I can add very small numbers together (nano + nano) or large numbers, but when trying to combine the two it starts to go wrong. Any advice on how to work around this? I am using c++11, and cannot use external libraries like boost.

(C++)Recursive function - don't know why this decrements

I'm just starting with recursive functions and know a some of how c++ works but I really don't understand how this code:

    void q9_draw_triangle(int a, int b) {

        // a is the starting point, b is the end
        if (a > b) return;

        // print pattern first
        for(int i = 0; i < a; i++){
            std::cout << "-";
        }
        std::cout << std::endl;

        // call on triangle where a is incremented once
        q9_draw_triangle(a+1,b);

        // print pattern last
        for(int i = 0; i < a; i++){
            std::cout << "-";
        }
        std::cout << std::endl;

    }

I get how the upper half works, it draws the first half of the triangle. When I stepped through this code using a debugger, once a > b happened it jumped to the last closing brace then to the last for loop and started drawing the second half of the triangle and decrementing itself back down to the starting a value. I have no idea why this happened or how one would know to do this to decrement.

Any help in understanding this is appreciated!

Applying or(||) operator on two vectors containing only 0 and 1

I have two vectors: A = {1,0,1,1}, B = {0,1,1,1}. How can I apply or operator on these two so that i could get a vector: C = {0,0,1,1} .

Compilation error when using Unique_ptr versus Shared_ptr as Class member

I am planning on porting some Python code to C++. I want to use C++11 techniques.

I have defined this class:

class Scenario
{

public:
    Scenario();
    ~Scenario();
private:
    std::shared_ptr<Scheduler> scheduler;
};

With empty constructor and destructor. This compiles.

However when changing shared_ptr to unique_ptr, compilation fails with a message that the default constructor is deleted and not accessible.

Question 1: Why?

The following:

class Scenario
{

public:
    Scenario();
private:
    std::unique_ptr<Scheduler> scheduler;
};

does compile however.

Question 2: Why does defining a destructor causes the constructor to be deleted.

How to compile FANN with C++ Wrapper

I am trying to compile FANN (Fast Artificial Neural Networks) with C++ Wrapper for this library. I follow this post in order to compile and execute XOR problem. But after

g++ -std=c++1y -Wall -Wextra -pedantic -l fann -o train xor_train_cpp.cpp

I get many similar errors like

/tmp/cc2VFdZC.o: In function FANN::training_data::read_train_from_file(std::string const&)': xor_cpp.cpp:(.text._ZN4FANN13training_data20read_train_from_fileERKSs[_ZN4FANN13training_data20read_train_from_fileERKSs]+0x2c): undefined reference tofann_read_train_from_file'

What is correct way to compile FANN with C++ Wrapper.

Note that I am able to successfully compile and execute its C analog.

Cereal serialization

I have a problem in C++11 with cereal (http://ift.tt/1jDSDLg).

I have a shared library, and I would like to serialize one of its classes using cereal library. Here is a part of the code of the library "I would like to serialize Object class":

"Object.hpp"

class ObjectPrivate;

class Object
{
 public:
    ...
    template <class Archive>
    void load(Archive& archive);

    template <class Archive>
    void save(Archive& archive) const;

 protected: 
    std::unique_ptr<ObjectPrivate> d_ptr;
};

template<>
void Object::load<cereal::BinaryInputArchive>(cereal::BinaryInputArchive& archive);

template<>
void Object::save<cereal::BinaryOutputArchive>(cereal::BinaryOutputArchive& archive) const;

"Object.cpp"

#include"Object_p.hpp"
template <class Archive>
void Object::load(Archive& archive)
{
    archive(d_ptr);
}

template <class Archive>
void Object::save(Archive& archive) const
{
    archive(d_ptr);
}

"Object_p.hpp"

#include"Object.hpp"

class ObjectPrivate
{
 public:
    int m_id;

    template<class Archive>
    void serialize(Archive & ar)
    {
        ar(m_id);
    }
};

but I got an error:

error: undefined reference to void GraphicalObject::save<cereal::BinaryOutputArchive>(cereal::BinaryOutputArchive&) const
error: undefined reference to void GraphicalObject::save<cereal::BinaryInputArchive>(cereal::BinaryInputArchive&) const

Preserving insertion_order on a std::set

Before marking this as duplicate, I have been here, here, and here, a duplicate of the first.

I'm aware of boost::multi_index, and use an environment where I lack it, and that a std::unordered_set is not bound to store elements in a deterministic insertion order.

I find the concept of using two containers, say an additional std::vector as uncouth.

What I would love is a solution involving a lambda comparator that I can use in a std::set's template parameters. Is it possible?