Riscriverei
evitando i double e pow, semplicemente comecodice:unsigned int PSize = static_cast<unsigned int>(pow(2,Size));
(poi probabilmente il compilatore lo fa lo stesso, ma non si sa mai)codice:unsigned int PSize = 1u<<Size;
Poi, il masking sul secondo byte è sbagliato - il numero totale di bit da considerare è Size, ma su quel byte saranno PSize-8 (e se PSize è <8 devi prevedere un caso particolare per fare masking sul primo byte e prendere da lì il bit del segno, o dare un qualche genere di errore). Quindi direi:
(alcune parentesi potrebbero non essere necessarie, ma le regole di precedenza sugli operatori bitwise in C sono bizzarre, per cui nel dubbio abbondocodice:if(Size<8) throw std::invalid_argument("Size must be >=8."); // o quel che ti pare tempPtr[1]=ptr[1] & (((1<<(Size-8)) - 1);)
Stessa questione per l'estrazione del segno: anche lì devi considerare la maschera per il secondo byte, non la maschera "globale"; tutto sommato, io quindi riscriverei il tutto così:
... ma, di nuovo, vedi se trovi documentazione più accurata su come vengono rappresentati i numeri negativi, che questa cosa non mi convince molto...codice:static inline float readF(const unsigned char * ptr, const int Size) { if(Size<8 || Size>15) throw std::range_error("Size must be >=8 and <=15."); unsigned char signMask = 1u<<(Size-8); unsigned short temp; float out=(ptr[1] & signMask) ? -1.f : 0.f; unsigned char * tempPtr=(unsigned char *) & temp; tempPtr[0]=ptr[0]; tempPtr[1]=ptr[1] & (signMask-1); out += float(temp) / float(1u<<Size); return out; }

)
Rispondi quotando
in ogni caso, sapere anche solo in linea di massima come funzionano i numeri in FP e i problemi ti dà un certo "timore reverenziale" nell'usarli
)



