Come gestire l’overflow e l’underflow?

Sono nuovo di Matlab e sto cercando di capire come posso gestire l’aritmetica di overflow e underflow quando la risposta è effettivamente all’interno dell’intervallo.

Per esempio:

x = 2e+160 x = x*x (which returns inf, an overflow) x = sqrt(x) (which is in the range) 

ogni aiuto è apprezzato.

Non sono un utente di Matlab, quindi tienilo a mente.

Il problema principale alla base di questo è innanzitutto rilevare overflow / underflow

Questo a volte è difficile perché appaiono anche in altri casi in cui il calcolo non restituisce zero o inf . Ad esempio durante l’overflow / underflow di integrazione numerica può causare un risultato errato ma comunque un numero diverso da zero.

Nella mia esperienza vedo come utile guardare i numeri nella loro rappresentazione esadecimale (a meno che i calcoli HW / SW non utilizzino la base decadica internamente per variabili che è raro perché la maggior parte di HW / SW è binario). Quindi vedere il numero in forma esadecimale e rilevare i modelli come ??????????.????FFFFFFFFFFF?? hex ??????????.????FFFFFFFFFFF?? hex quando si guarda la parte frazionaria e si rileva che molti FFFFF sono presenti vicino alle cifre più basse, quindi il numero è molto probabile che trabocchi o sia molto vicino a quel punto. Il numero di zeri o quanto mai alla fine di solito diminuisce a ogni iterazione saturando l’ ??????????.????FFFFFFFFFFF hex . Gli overflow sono saturi simillari ma dall’altra parte in questo modo: FFFFFFFFFFF.FFFFFF?????? hex FFFFFFFFFFF.FFFFFF?????? hex Per alcuni algoritmi è più preciso arrotondare su / giù tali numeri prima dell’iterazione successiva, ma è necessario verificare sempre se questo è il caso su alcuni esempi ben noti di computazioni prima di applicare su incognite … Guarda qui il divisore in virgola mobile è un bell’esempio di algoritmo utilizzando questa tecnica

Un altro modo per rilevare overflow / underflow è la previsione dell’ampiezza del numero di risultati. Per esempio

  • * sum gli esponenti insieme
  • / sottrai gli esponenti
  • sqrt dimezza l’esponente
  • +, – può risultare in +1/-1 dell’esponente più grande

Quindi, se hai a che fare con esponenti grandi / piccoli, sai quali operazioni potrebbero portare a problemi di overflow.

Oltre a ciò possono verificarsi dei underflow quando la precisione dei risultati non si adatta alla mantissa. Quindi devi fare attenzione con le operazioni che aumentano i bit usati del risultato come:

  • a*b sum dei bit usati in a , b
  • +,- max bit usato di (a, b) – min bit usato di (a, b)
  • / aggiunge alcuni bit per contenere le frazioni …

L’operazione +,- è la peggiore, ad esempio se si aggiunge 2^100 + 2^-100 allora il risultato ha bisogno di 200 bit di mantissa mentre gli operandi stessi hanno una cabina di appena 1 bit di mantissa.

Cosa fare se viene rilevato overflow / underflow:

  1. cambiare equazione

    Come accennato, puoi passare al log grado di gestire gli intervalli più grandi con facilità, ma hanno altri problemi. Inoltre, in genere un leggero cambiamento nell’algoritmo può portare a risultati scalati in base a fattori diversi, ma con risultati secondari ancora nell’intervallo di sicurezza, quindi è sufficiente il risultato finale per ridimensionare l’intervallo pericoloso. Mentre si cambiano le equazioni, è necessario tenere sempre in considerazione la precisione e la validità del risultato.

  2. usa un tipo di dati variabile più grande

    Se ricordo bene, Matlab ha numeri di precisione arbitrari, quindi usali se necessario. È inoltre ansible utilizzare variabili standard float/double e memorizzare il valore in più variabili, ad esempio aumentare la precisione dell’integrazione numerica

  3. smettere di iterare

    Ad esempio alcuni algoritmi usano serie come 1/1! + 1/2! + 1/3! + ... + 1/n! 1/1! + 1/2! + 1/3! + ... + 1/n! in alcuni casi, se rilevi di colpire il subresult straripante / in piena mano quando interrompi l’iterazione, hai comunque un risultato relativamente accurato del calcolo. Non dimenticare di non includere sub-overflow al risultato finale.