C MPFRC Как использовать memcpy() с mpfr ::mpreal?

#c #memcpy #mpfr

#c #memcpy #mpfr

Вопрос:

Я не смог найти ничего, связанного с этим вопросом. Предположим, у меня есть два mpfr::mpreal массива a и b , в куче, как new mpfr::mpreal[n] . Я должен использовать массивы в стиле C из-за функции, которая вызывает и использует массивы. Я не могу его изменить, я пытался, но это дает неправильные результаты, плюс сбои, это довольно большая и сложная функция для моего уровня. Если массивы могут быть большими (как размер, так и тип / точность), я бы хотел избежать цикла для копирования, и я хотел бы использовать memcpy() вместо этого. Что я должен использовать в качестве 3-го аргумента?

Я пытался sizeof(mpfr::mpreal) , но он всегда выдает 32 , независимо от того, что я использую mpfr_set_default_prec() . На домашней странице я видел, что я могу использовать mpfr::machine_epsilon() для лучшего отображения этого, но как я могу использовать его в memcpy() ?

Комментарии:

1. I'd like to avoid a loop for copying and I'd like to use memcpy() instead . Это не очень хорошая идея. mpfr использует большие целые числа для мантиссы и, вероятно, выделяет некоторую часть информации в куче. Такая информация не предназначена для совместного использования между различными mpreal — чтобы избежать двойных ошибок.

2. Я не знал, как они обрабатываются под капотом, но это имеет большой смысл.

Ответ №1:

mpfr::mpreal Переменная (или их массив) является объектом C , она не может быть скопирована memcpy правильно. Вместо этого используйте std::copy или цикл.

Он memcpy просто копирует блоки памяти по битам, что отлично работает для простых структур данных в стиле POD C. Объекты C следует копировать, вызывая оператор присваивания, Чтобы объект мог самостоятельно распределять память и т. Д.

Размер mpfr::mpreal всегда один и тот же, поскольку он просто содержит указатель на мантиссу, которая выделяется в куче в другой ячейке памяти. memcpy Копирует только указатель, он не перераспределяет мантиссу, и, таким образом, исходные и целевые mprreals будут указывать на одну и ту же мантиссу в памяти. Это именно то, чего следует избегать. В свою очередь, std::copy хорошо об этом заботится — копируя каждый объект в цикле с помощью оператора присваивания класса mprreal (который выполняет необходимые перераспределения и т. Д.)

(Я автор MPFR C ).

Комментарии:

1. Спасибо за объяснение. Причина, по которой я спросил, заключалась в том, что я совсем недавно видел страницу, на которой было показано, что неоптимизированный код был намного медленнее для копирования массива, чем memcpy() (также быстро проверил сам). Оптимизированный, производительность была одинаковой для некоторых компиляторов. В общем, я просто выберу цикл, так как это кажется наиболее простым делом. Мне не особенно нравится std::copy или что-либо написанное под капотом из-за общего использования, для которого они были созданы, и (незначительных) накладных расходов, которые возникают в конкретных случаях, таких как мой.