Правильный способ работы с точными числами в CGAL - PullRequest
0 голосов
/ 22 ноября 2018

Рассмотрим следующий минимальный пример:

#include <stdlib.h>

#include "CGAL\Exact_predicates_exact_constructions_kernel.h"

typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::FT NumberType;

int main()
{
    int numberOfIterations = 4000;

    NumberType sum = 0;
    for (int i = 0; i < numberOfIterations; i++)
    {
        sum += 1;
    }

    std::cout << "Sum = " << sum << std::endl;

    getchar();

    return 0;
}

Все работает нормально, если параметр numberOfIterations принимает небольшие значения.Однако, если для него установлено значение, превышающее несколько тысяч, программа выводит правильное значение для sum, но выдает Ошибка переполнения стека (параметры: 0x0000000000000001, 0x000000C4D2EF3FF8) при удалении памяти (Iпредположим).

Я прочитал документацию CGAL по типам чисел , но мне непонятно, почему это происходит.Что я должен сделать для правильного выполнения операций над точными числами?

Вот более сложный пример (как указано в комментариях ниже), строго связанный с моей первоначальной задачей:

#include <stdlib.h>

#include <CGAL/number_utils.h>
#include "CGAL/Exact_predicates_exact_constructions_kernel_with_sqrt.h"
#include "CGAL/Polyhedron_3.h"

typedef CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron_3;
typedef Kernel::FT NumberType;
typedef Kernel::Vector_3 Vector_3;
typedef Kernel::Direction_3 Direction_3;

Direction_3 sampleFunction(std::vector<Vector_3> vectors)
{
    NumberType denominator = 0;
    NumberType numeratorX = 0;
    NumberType numeratorY = 0;
    NumberType numeratorZ = 0;

    for (int vf = 0; vf < vectors.size(); vf++)
    {
        Vector_3 vectorF = vectors.at(vf);

        numeratorX += vectorF.x();
        numeratorY += vectorF.y();
        numeratorZ += vectorF.z();

        for (int vg = 0; vg < vectors.size(); vg++)
        {
            Vector_3 vectorG = vectors.at(vg);

            denominator += CGAL::scalar_product(vectorF, vectorG);
        }
    }
    NumberType lambda = CGAL::sqrt(denominator);

    NumberType x = numeratorX / lambda;
    NumberType y = numeratorY / lambda;
    NumberType z = numeratorZ / lambda;

    Vector_3 result(x, y, z);

    return result.direction();
}

int main()
{
    int numberOfVectors = 100;

    std::vector<Vector_3> vectors;
    srand(0);
    for (int i = 0; i < numberOfVectors; i++)
    {
        Vector_3 newVector(rand() % 100 - 50, rand() % 100 - 50, rand() % 100 - 50);
        newVector /= CGAL::sqrt(newVector.squared_length());
        vectors.push_back(newVector);
    }

    Direction_3 direction = sampleFunction(vectors);

    std::cout << direction.dx() << " " << direction.dy() << " " << direction.dz() << " " << std::endl;

    return 0;
}
...