2013-05-10 13 views
8

Dire che ho questo numero :Come aumentare le parti di numero multiprecisione?

// bmp = boost::multiprecision 
bmp::cpp_dec_float n("123456789.1234567891011121314"); 

i suoi dati di back-end sono:

[0] 1   unsigned int 
[1] 23456789 unsigned int 
[2] 12345678 unsigned int 
[3] 91011121 unsigned int 
[4] 31400000 unsigned int 
... 0 
[15] 0   unsigned int 

che è esattamente quello che voglio ottenere; sfortunatamente, non trovo un modo per ottenere entrambe le parti del mio numero come bmp::int128_t - per esempio--, oi dati sottostanti del mio numero.

Cioè, mi piace esiste qualcosa di simile:

bmp::int128_t integerPart; 
bmp::int128_t floatPart; 
n.getParts(integerPart, floatPart); 

o

auto&& data = n.data(); // which is actually private when using `cpp_dec_float`. 

In ogni caso, Qualcuno sa come fare quello che sto cercando di realizzare?

Per la registrazione, ho bisogno di questo per esprimere un numero decimale grande come C# decimale nell'interesse dell'interoperabilità.

risposta

-1

Ho il sospetto che sia possibile utilizzare eval_frexp per ottenere i valori che si stanno cercando, sebbene sia ancora necessario verificare che si adattino al tipo C# Decimal. Vedere il manuale sui requisiti di backend Boost.Multiprecision qui: http://www.boost.org/doc/libs/1_53_0/libs/multiprecision/doc/html/boost_multiprecision/ref/backendconc.html

Si può sempre eseguire solo il controllo di matematica e intervallo di longhand; se non trasferisci troppi numeri, questo potrebbe essere abbastanza veloce.

Detto tutto questo, siete i benvenuti a essere cattivo e fare qualcosa di simile:

#define private public 
#define protected public 
#include <boost/multiprecision/cpp_dec_float.hpp> 
#undef private 
#undef protected 

Ma se si rompe in una versione futura, si arriva a mantenere entrambi i pezzi.


Ehi, grazie per il downvot senza commento. Questo è davvero utile.

di chiarire la mia osservazioni di cui sopra:

Utilizzando eval_frexp: dopo ulteriori ricerche, sembra che il eval_frexp(b, cb, pi) è ancora solo offrono potenze di 2, non potenze di 10 come sembra essere richiesta per il tipo Decimal. Quindi sospetto che tu debba fare l'aritmetica in forma estesa se vuoi usare solo l'interfaccia pubblica.

Uso abusivo private membri: Gli autori e i manutentori delle classi Boost.Multiprecision li hanno progettati secondo determinate linee guida; a quanto pare classificati a prova di futuro, come più importante di fornire l'accesso alla struttura interna:

modello Classe cpp_dec_float soddisfa tutti i requisiti per un tipo di backend. I suoi membri e le sue funzioni non membri sono deliberatamente non documentati: questi sono considerati dettagli di implementazione che sono soggetti a modifiche. (http://www.boost.org/doc/libs/1_53_0/libs/multiprecision/doc/html/boost_multiprecision/ref/cpp_dec_ref.html)

La mia proposta, che era chiaramente contrassegnato come "cattivo" e con l'avvertimento che sarebbe probabilmente rompere in una versione futura, era di imporre le esigenze di progettazione del PO davanti a quelle dell'autore della B.MP.

Il metodo molto più pulito potrebbe essere quello di proporre una modifica alla classe cpp_dec_float, dove è esposta la struttura interna; dato un caso d'uso convincente e un'analisi di quanto il codice sia o non sia cambiato storicamente, potrebbe persino essere accettato.

Spero che questo aiuti. Se i lettori continuano a riscontrare problemi, non esitate a inoltrare per favore, ma fatemi sapere quale parte vi preoccupa, quindi posso provare a migliorarlo.

+0

Non sono stato io , ma le parole chiave '' define'ing 'sono un comportamento indefinito e (quasi?) mai una soluzione solida ai problemi –

+0

Oh, nessuna discussione lì. Ho cercato di esprimere la risposta originale (e il mio commento sniffato sul downvote) per essere chiari sul fatto che questo non è qualcosa che è una buona idea per l'uso in produzione. Se l'OP ha davvero bisogno di questa capacità a lungo termine, allora se non riescono a convincere i manutentori di B.MP, dovrebbero semplicemente biforcarlo e succhiarlo nella loro base di codice - la BPL lo consente. Stavo solo cercando di offrire una soluzione "è alle 23.00 e ne hai bisogno domani". Forse vale un downvote, non so. – AnthonyFoiani

+0

Aneddoto divertente: ho cercato di creare un meme "#define public privato: NO REGRETS" sul generatore di meme interno presso la mia azienda attuale ... solo per essere reindirizzato a un esempio * esistente *. Quindi immagino di non essere l'unica anima demente con questa idea. :) – AnthonyFoiani

0

Non so se questo è che si sta cercando, prova ...

cpp_dec_float_100 myreal(100); 
cpp_dec_float_100 int_part = myreal.backend().extract_integer_part(); 

Il tipo è ancora cpp_dec_float_100, ma contiene solo la parte intera. Spero che questo aiuti.

1

Dalla documentazione spinta il back-end volutamente opaco come può cambiare in qualsiasi momento senza preavviso. (Class template cpp_dec_float fulfils all of the requirements for a Backend type. Its members and non-member functions are deliberately not documented: these are considered implementation details that are subject to change.) da http://www.boost.org/doc/libs/1_55_0/libs/multiprecision/doc/html/boost_multiprecision/ref/cpp_dec_ref.html

Per quanto posso vedere, qui ci sono due scelte. Puoi guardare il codice sorgente per la versione specifica della classe di backend che stai utilizzando, accedervi dal tuo number usando il metodo backend, e sperare che il backend non cambi mai (specialmente considerare le modifiche che hanno rotto solo il formato binario e non la compilazione) .

In alternativa vi consiglio di prendere la rappresentazione di stringa del cpp_dec_float e dividerlo in due parti da soli, utilizzando le string o char* costruttori per i tipi integrali sottostanti che ti interessa.

+0

+1, con la nota aggiuntiva che la licenza pubblica Boost consente di copiare praticamente per qualsiasi uso, incluso quello commerciale. Se la rappresentazione interna se qualche versione è esattamente ciò di cui l'OP ha bisogno/vuole, allora se i proprietari di Boost.MultiPrecision non possono essere convinti di congelare un'implementazione, l'OP può bloccarlo autonomamente. – AnthonyFoiani

Problemi correlati