2016-10-09 2 views
0

Je n'ai rien trouvé à propos de cette question. Supposons que j'ai deux tableaux mpfr::mpreal, a et b, dans le tas, comme new mpfr::mpreal[n]. Je dois utiliser des tableaux de style C à cause d'une fonction qui appelle et utilise les tableaux. Je ne peux pas le modifier, j'ai essayé, mais ça donne de mauvais résultats, plus des plantages, c'est une fonction assez grande et compliquée pour mon niveau. Si les tableaux peuvent devenir grands (à la fois taille et type/précision), je voudrais éviter une boucle pour la copie et je voudrais utiliser memcpy() à la place. Que devrais-je utiliser comme 3ème argument? J'ai essayé sizeof(mpfr::mpreal) mais il donne toujours 32, peu importe ce que j'utilise dans mpfr_set_default_prec(). Dans la page d'accueil, j'ai vu que je peux utiliser mpfr::machine_epsilon() pour mieux afficher cela, mais comment puis-je l'utiliser dans memcpy()?C++ MPFRC++ Comment utiliser memcpy() avec mpfr :: mpreal?

+0

'Je voudrais éviter une boucle pour la copie et je voudrais utiliser memcpy() à la place'. Ce n'est pas une bonne idée. mpfr utilise de grands entiers pour la mantisse et est susceptible d'allouer une partie de l'information dans le tas. De telles informations ne sont pas destinées à être partagées entre différents «mpreal» - pour éviter les doubles erreurs. – Franck

+0

Je ne savais pas comment ils ont été manipulés sous le capot, mais cela a beaucoup de sens. –

Répondre

2

La variable mpfr::mpreal (ou tableau d'entre eux) est un objet C++, il ne peut pas être copié par memcpy correctement. Utilisez std :: copy ou loop à la place.

Le memcpy ne fait que copier des blocs de mémoire bit par bit, ce qui fonctionne bien pour les structures de données de type POD C simples. Les objets C++ doivent être copiés en appelant l'opérateur d'affectation afin que l'objet puisse prendre des allocations de mémoire, etc.

La taille de mpfr::mpreal est toujours la même, car elle contient uniquement un pointeur vers la mantisse, qui est allouée en tas dans un emplacement de mémoire différent. Le memcpy ne copie que le pointeur, il ne réalloue pas la mantisse et donc les mpreals source et destination pointent vers la même mantisse en mémoire. C'est exactement ce qui devrait être évité. À son tour, std::copy prend soin de ce bien - en copiant chaque objet dans une boucle en utilisant l'opérateur d'affectation de classe mpreal (qui fait les réaffectations nécessaires, etc.)

(Je suis auteur de MPFR C++).

+0

Merci pour l'explication. La raison pour laquelle j'ai demandé était parce que j'ai vu, très récemment, une page où il a montré que le code non optimisé était beaucoup plus lent pour la copie de tableau que 'memcpy()' (également fait une vérification rapide). Optimisées, les performances étaient similaires pour certains compilateurs. Dans l'ensemble, je vais juste choisir la boucle, car il semble que la chose la plus directe à faire. Je n'aime pas particulièrement 'std :: copy' ou quoi que ce soit d'écrit sous le capot à cause de l'usage général pour lequel ils ont été faits et des (légers) frais généraux que cela entraîne pour des cas particuliers, comme le mien. –