2015-09-24 17 views
13

Sto cercando di compilare la libreria ExprTk con maggiore precisione rispetto a long double. Ho pensato che il semplicista sarebbe stato quello di provare GCC __float128 ma sto ricevendo il seguente errore di compilazione e non sono sicuro di come correggerlo.EsprTk con maggiore precisione

exprtk.hpp: In instantiation of ‘static T exprtk::details::and_op<T>::process(exprtk::details::and_op<T>::Type, exprtk::details::and_op<T>::Type) [with T = __float128; exprtk::details::and_op<T>::Type = const __float128&]’: 
exprtk.hpp:28439:10: required from ‘void exprtk::parser<T>::load_binary_operations_map(exprtk::parser<T>::binary_op_map_t&) [with T = __float128; exprtk::parser<T>::binary_op_map_t = std::map<exprtk::details::operator_type, __float128 (*)(const __float128&, const __float128&), std::less<exprtk::details::operator_type>, std::allocator<std::pair<const exprtk::details::operator_type, __float128 (*)(const __float128&, const __float128&)> > >; typename exprtk::details::functor_t<T>::bfunc_t = __float128 (*)(const __float128&, const __float128&)]’ 
exprtk.hpp:15660:51: required from ‘exprtk::parser<T>::parser(std::size_t) [with T = __float128; std::size_t = long unsigned int]’ 
mathtof.cpp:18:33: required from here 
exprtk.hpp:9923:105: error: call of overloaded ‘is_true(const __float128&)’ is ambiguous 
      static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); } 
                             ^
compilation terminated due to -Wfatal-errors. 

EDIT:

Ho provato attuazione mia is_true

<typename T> 
inline bool is_true(const T v) 
{ 
    return std::not_equal_to<T>()(T(0),v); 
} 
+0

'is_true' vs' is_true_impl'? Inoltre, in base all'errore, è necessario inserirlo nello spazio dei nomi 'details'. 'is_true' è chiamato usando un nome qualificato, quindi ADL non si innescherà. –

+0

Il mio errore, era 'is_true'.L'ho fatto copiando che 'is_true_impl' è direttamente in linea con le altre definizioni di' is_true' e 'is_ture_impl'. –

+0

Il tuo tentativo di definire l'account 'is_true' per lo spazio dei nomi? –

risposta

15

È piuttosto banale specializzare ExprTk su un tipo numerico personalizzato. Ci sono due esempi trovati nella pagina del progetto che forniscono un mezzo chiaro e conciso per introdurre nuovi tipi numerici all'interno di ExprTk.

Gli esempi sono:

  1. Personalizzata tipo reale adattatore [link]
  2. adattatore MPFR [link]

L'esempio di tipo reale implementa un semplice vero e proprio tipo utilizzando il tipo double. Inoltre fornisce le aggiunte necessarie nello spazio dei nomi ExprTk che deve essere incluso prima di includere l'intestazione ExprTk effettiva.

L'adattatore MPFR si basa sull'esempio precedente e mostra come si può facilmente adattare il tipo MPFR/GMP per l'uso in ExprTk.

Entrambi gli esempi vengono forniti con l'intera suite di test e il benchmark utilizzando i nuovi tipi introdotti.


Ecco un esempio in cui qualcuno ha adattato il proprio tipo chiamato DScalar a ExprTk:

https://github.com/filiatra/gismo/blob/stable/external/exprtk_ad_adaptor.hpp

e qui viene utilizzato:

https://github.com/filiatra/gismo/blob/stable/src/gsCore/gsFunctionExpr.hpp#L146


Va notato che si può semplicemente prendere il "Custom reale Tipo Adapter" e Search-n-sostituire la stringa "reale :: tipo" con __float128 e alcuni altri minori sostituire modifiche e dovrebbe essere tutto bene andare.

+0

Il mio barattolo è letteralmente caduto. Ho promesso di guardare lì prima di chiedere qui. –

+0

L'esempio dell'adattatore fornito in realtà non viene compilato per me. Non ho ancora provato MPFR. –

+3

@chewsocks si scaricano di nuovo entrambi, potrebbe essersi verificato un problema con printf - assicurati anche di copiare exprtk.hpp nel punto in cui è necessario in quanto entrambi i pacchetti non includono l'intestazione come parte del download. –

0

E, ovviamente, non supporta __float128 (GCC si sostiene a malapena, è necessario il Boost float128.h biblioteca per fare qualsiasi cosa lontanamente utile con esso).

Si può provare a fornire il sovraccarico di is_true(__float128&) mancante, dovrebbe essere relativamente banale, ma sono disposto a scommettere i soldi che non saranno la fine di esso.

+0

Nota che la mia conoscenza del supporto di gcc per' __float128' è di qualche anno, forse le versioni più recenti sono migliorate, anche se ne dubito. Non c'è molto mercato per le operazioni in virgola mobile emulate dal software quando puoi fare miliardi alla volta nella tua varietà di giardini GPU :) – Blindy

+0

Ok, quindi l'ho cambiato usando 'boost :: multiprecision :: cpp_dec_float_100' perché l'ho capito avrebbe una serie più completa di sovraccarichi. No, lo stesso problema. –

+0

Non sono sicuro di cosa intendi per fare calcoli in virgola mobile su una GPU. Il vantaggio di un'implementazione software è l'alta precisione. Fino a poco tempo fa una GPU poteva fare solo float a 32 bit. –

Problemi correlati