#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
или что-либо написанное под капотом из-за общего использования, для которого они были созданы, и (незначительных) накладных расходов, которые возникают в конкретных случаях, таких как мой.