Ho una domanda riguardante l'aritmetica in virgola mobile in java e la sua precisione. Ho fatto le mie ricerche qui e tramite Google e ho trovato alcune soluzioni, ma ho difficoltà ad implementarle nel mio progetto. Quindi in Java sto facendo uso della classe BigDecimal per ottenere i miei calcoli precisi. Si noti che le variabili sono doppie e i valori possono avere una precisione fino a 8 posizioni decimali a destra durante i calcoli. Il risultato (precisione) da visualizzare è noto e questo è ciò che memorizzerò come valore corrente. Inoltre, tutti i valori arrivano in modo dinamico (attraverso un metodo). L'argomento passato dovrebbe essere il valore corrente + la dimensione del passo.Problema di virgola mobile Java Problema
public void newValue(float value) {
//Clip to valid range, can't go over minimum/max value
value = Math.max(minimumValue, Math.min(maximumValue, value));
// TODO Implement better Floating Point Arithmetic precision
MathContext mcI = new MathContext(0, RoundingMode.HALF_UP);
MathContext mcF = new MathContext(8, RoundingMode.HALF_UP);
BigDecimal valueBD = new BigDecimal(value, mcF);
BigDecimal minimumBD = new BigDecimal(minimumValue, mcF);
BigDecimal stepBD = new BigDecimal(step, mcF);
BigDecimal currentValueBD = new BigDecimal(currentValue, mcF);
BigDecimal totalStepsBD = valueBD.subtract(minimumBD, mcF);
//Ensure value is divisible by stepsize
totalStepsBD = totalStepsBD.divide(stepBD, mcI);
valueBD = stepBD.multiply(totalStepsBD, mcF);
valueBD = valueBD.add(minimumBD, mcF);
// arithmetic without using BigDecimal (old)
//int totalSteps = (int) ((value- minimumValue)/ step);
//value = totalSteps * step + minimumValue;
if(!(valueBD.equals(currentValueBD))) {
valueBD = valueBD.setScale(displayPrecision, RoundingMode.HALF_UP);
currentValue = valueBD.floatValue();
dispatch();
}
}
Ora, funziona con alcuni valori, ma non tutti. Soprattutto quando ho problemi con le dimensioni del passo. Quindi se step = 0.1 andava bene. Se ho fatta 0,005, mi piacerebbe avere un AirthmeticException - sviluppo decimale non termina sul gradino dove
totalStepsBD = totalStepsBD.divide(stepBD, mcI);
Quando .005 è impostato per la variabile passo, dopo aver fatto un BigDeciaml (stepBD) esce a. 0049999999 ... Non so se questo ti aiuta ma se hai qualche idea per favore fammelo sapere. Grazie.
non vedo una che si definisce 'step' da nessuna parte, quindi sto supponendo che è una variabile membro alla la classe. Se è un tipo 'float' e viene assegnato 0.005, verrà salvato come .0049999999 o qualcosa di simile. Quando si assegna 'stepBD' al valore di' step', utilizza i valori 0,00499, non 0,005. Non sono sicuro se questo è il problema, ma potrebbe essere d'aiuto. – Grice
Nota: non usare '.equals()' per confrontare 'BigDecimal's; per esempio, '0' e' 0.00' non sono uguali. Usa '.compareTo()' e controlla '== 0' invece. – fge