Come gestire l'errore di arrotondamento<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Ho questo script che esegue un semplice calcolo e visualizza il risultato in una finestra:
subtotale = 100.05 ;
sconto% = 0.1 ;
discountAmount = subtotale * discountPercent;
totalBeforeTax = subtotale - discountAmount;
formattedMessage = Concat (
"Totale parziale:" , Ripetere ( " " , 5 ), Formato (totale parziale, "Valuta" ), "\!N" ,
"Percentuale di sconto:" , Ripetere ( " " , 5 ), Formato (percentuale di sconto, "Per cento" ), "\!N" ,
"Totale sconto:" , Ripetere ( " " , 5 ), Formato (totale sconto, "Valuta" ), "\!N" ,
"Totale tasse escluse:" , Ripetere ( " " , 5 ), Formato (totale tasse escluse, "Valuta" ), "\!N"
);
formattedMessageDisplay = Nuova finestra ( "Risultato" ,
Casella di formazione ( N col ( 1 ), Spaziatura( 0 , 0 ), Casella di confine ( Sinistra ( 20 ), Giusto ( 20 ), superiore( 20 ), metter il fondo a( 20 ),
Casella di testo (Message formattato, << Imposta dimensione carattere ( 14 ) ) )
),
Spettacolo (subtotale, discountAmount, totalBeforeTax)
);
Produce quanto segue, nel registro e nella finestra di output:



Quindi usando Formato (totale tasse escluse, "Valuta" ), risultati in totalBeforeTax essendo "arrotondato per eccesso". Posso pensare a una varietà di modi per gestirlo, ma mi chiedevo quale sarebbe il più raccomandato.
Ri: Come gestire l'errore di arrotondamentoNessun piano Big Number in questo momento.Sono stati fatti molti punti interessanti nel collegamento StackOverflow.Diverse soluzioni potrebbero essere appropriate a seconda di cosa farai con i numeri.
Craige
Ri: Come gestire l'errore di arrotondamentoUn'altra cosa a cui ho pensato è stata convertire in stringa e utilizzare Regex.
Ri: Come gestire l'errore di arrotondamentoGrazie Craige, in effetti ho preso in considerazione la creazione di un'interfaccia per consentire a JMP di accedere alla classe BigDecimal di Java. Ci sono piani per includerlo come tipo nella prossima versione di JMP?
Ri: Come gestire l'errore di arrotondamentoPotresti voler arrotondare/minimo/massimale il calcolo dell'importo dello sconto.Round ha un secondo argomento che potresti voler impostare su 2 per le cifre dopo il decimale.Floor e ceiling avranno bisogno di qualcosa come floor(x*100)/100 per ottenere un risultato simile.
subtotale = 100,05;
discountPercent = 0,1;
importosconto = girare (subtotale * discountPercent, 2) ;
totalBeforeTax = subtotale - discountAmount;
show(importosconto, totaleBeforeTax);
importosconto = 10,01;
totaleBeforeTax = 90,04;
La funzione di formato nel codice originale è sul filo del rasoio dell'arrotondamento per eccesso o per difetto con lo 0,005 arrotondato a due posizioni.La discrepanza nella presentazione è innescata dal valore che ha un meno in un caso e un più nell'altro...entrambi i valori sono arrotondati per eccesso, ma uno di essi ha un importo di sconto negativo nel calcolo.
I numeri in virgola mobile utilizzati in JMP rappresentano numeri come 0,01 come frazione binaria ripetuta troncata.Proprio come 1/3 non è esattamente 0,333333333333, la rappresentazione interna non è esatta (ad eccezione delle frazioni binarie come 1/2, 1/4, 1/8, ...). se sommi 100 centesimi, rappresentati come 0,01, otterrai un numero molto vicino a 1,00, ma diverso nella 16° cifra decimale.Questo minuscolo errore ha sempre fatto sì che i pacchetti contabili scegliessero un'altra rappresentazione: java - Perché non usare Double o Float per rappresentare la valuta? - Stack Overflow
totale = 0;
For( i = 1, i <= 100, i++, totale += .01 );
show( format(total,"fixed",20,16) );
Formato(totale, "fisso", 20, 16) = "1.0000000000000007";
Ri: Come gestire l'errore di arrotondamentoCiao Jim,
Grazie per la tua risposta. Quindi, Floor e Ceiling vengono arrotondati all'intero più vicino. Il formato (x, "Currency") sembra utilizzare Round(x,2). Si potrebbe pensare che il formato "Valuta" utilizzi un metodo di troncamento piuttosto che di arrotondamento.
Ri: Come gestire l'errore di arrotondamentoNon eseguo molti report finanziari, tuttavia, quando devo preoccuparmi degli errori di arrotondamento, utilizzo solo le funzioni Round(),Ceiling() e Floor().