Convertitore di valuta in Java con problemi di precisione e condensazione


Ho ottenuto un incarico che deve essere scritto in Java.

Dobbiamo sviluppare un'applicazione di conversione di valuta che chiede la valuta da cui stanno convertendo, la quantità di detta valuta e la valuta in cui desiderano convertire.

L'istruzione ha notato che dovremmo includere 4 valute da convertire da/a.

Ho ricevuto il compito presto e sono andato a mostrare la mia professoressa e ha notato un paio di problemi con esso. Le piace l'organizzazione e la chiarezza del codice, ma lei pensa che possa renderlo un po ' più piccolo e risolvere un problema che ho con precisione decimale.

Per quanto riguarda la sua realizzazione più breve, il suo argomento principale era che ho 7 costanti che detengono i tassi di cambio. Ero piuttosto orgoglioso di questo dato che 7 tariffe è molto più breve di 12 tariffe individuali per ogni possibile combinazione. Il codice è sotto.

// Conversion Rates - START (as of October 14, 2018 @ 1:03 AM)
// Rates obtained from exchange-rates.org
private final double USD_TO_USD = 1;

//Convert to United States Dollars
private final double CAD_TO_USD = 0.76792;
private final double EUR_TO_USD = 1.1407;
private final double YEN_TO_USD = 0.008923;

//Convert from United States Dollars
private final double USD_TO_CAD = 1.3022;
private final double USD_TO_EUR = 0.87662;
private final double USD_TO_YEN = 112.06;
// Conversion Rates - END

Il mio processo di pensiero dietro la mia metodologia è convertire tutto in dollari USA, quindi convertire da NOI Dollari alla valuta di destinazione. Non sono sicuro di come condensare ulteriormente questo, quindi questo è uno dei problemi che sto avendo.

Il problema principale che sto incontrando è la precisione. Poiché la classe è in gran parte basata sulla matematica aziendale, i programmi sono generalmente utilizzati per convertire milioni/miliardi di valuta. So che double ha già i suoi problemi ereditari con precisione, ma non sono sicuro di quali altri tipi di dati utilizzare. Mi sono imbattuto in BigDecimal, e darò un'occhiata in quello dopo aver postato questo.

A mio avviso, il numero di punti decimali nel tasso di cambio influenzerà direttamente la precisione del risultato. i numeri più a destra del tasso; il meglio. Dovrei prendere l'abitudine di includere una quantità molto grande di punti decimali per rendere molto difficile il problema della precisione? O l'uso di BigDecimal di solito risolverebbe il problema.

Ho considerato di abbandonare l'uso di double e usare invece int; so invece di una doppia holding 5.00, avrei un numero intero con 500; ma a questo punto, non sono sicuro del modo "corretto" di procedere.

Così sono venuto a chiedervi brave persone: D

Sono felice di imparare il più possibile, quindi qualsiasi assistenza è apprezzata.

Grazie

AGGIORNARE: Ho preso un po ' di tempo per controllare BigDecimal, e l'ho fatto funzionare; tranne che ora sono fuori da un importo che va da 1 a 10 (potrebbe essere più in numeri molto grandi, ma non l'ho testato più di 5 volte con numeri diversi).

Nel mio test, ho convertito 98765432,00 Yen giapponesi in dollari USA, con un tasso di 1 YEN = 0,008907 dollari USA. Secondo il sito web che ho usato per verificare al momento-il risultato in dollari USA dovrebbe essere USD USD 879,701.24; ma sto ricevendo $879,703.70 sul mio programma. Anche la mia calcolatrice scientifica sta ottenendo la stessa cosa che il mio programma java sta ottenendo.

Author: Bryan Douglas, 2018-10-26

2 answers

Vai avanti con il tuo approccio di implementazione con BigDecimal come con BigDecimal non perderai alcuna precisione ma con double c'è la possibilità di perdere quando hai a che fare con numeri più grandi.

Si prega di passare attraverso il link qui sotto stackoverflow per avere più idea su BigDecimal: Doppio contro BigDecimal?

Siete sulla strada giusta, tenere a dondolo e apprendimento felice.

 0
Author: Udaya Shankara Gandhi Thalabat, 2018-10-26 04:20:55

Ecco un'altra implementazione:

Dato un elenco di tassi di cambio come questo:

USD/GBP => 0.75 
GBP/AUD => 1.7 
AUD/JPY => 90 
GBP/JPY => 150 
JPY/INR => 0.6

Write a method

double convert(String sourceCurrency, double amount, String destCurrency);

==============

package test;

import java.util.*;

public class CurrencyConvertor {
    private Map<String, Map<String, Double>> mapping = new HashMap<String, Map<String, Double>>();
    private boolean bInit = false;
    private boolean bFound = false;

    double convert(String src, double amount, String dst) throws Exception {
        if (src.equals(dst))
            return amount;

        if (!bInit) {
            init();
            bInit = true;
        }

        bFound = false;
        if (mapping.get(src) == null) {
            throw new Exception("Invalid conversion");
        }

        List<String> visited = new ArrayList<String>();
        visited.add(src);
        double d1 = getRate(visited, src, dst, 1);
        if (bFound)
            return d1 * amount;
        throw new Exception("No mapping invalid conversion");
    }

    private double getRate(List<String> visited, String src, String dst, double rate) throws Exception {
        if (bFound == true) {
            return rate;
        }

        if (mapping.get(src).get(dst) != null) {
            bFound = true;
            return rate * mapping.get(src).get(dst);
        }

        double origRate = rate;
        for (String sInt : mapping.get(src).keySet()) {
            if (visited.contains(sInt)) {
                continue;
            }
            visited.add(sInt);
            rate = getRate(visited, sInt, dst, rate * mapping.get(src).get(sInt));
            if (bFound == true) {
                return rate;
            }
            visited.remove(sInt);
            rate = origRate;
        }

        return origRate;
    }

    private void init() {
        // Invalid case data, EUR to INR
        insert("EUR", "USD", 1.2);
        insert("USD", "EUR", 0.75);
        insert("YEN", "INR", 1.2);
        insert("INR", "YEN", 0.75);

        // Valid case data, EUR to INR
        // insert("EUR", "USD", 1.2);
        // insert("USD", "GBP", 0.75);
        // insert("GBP", "AUD", 1.7);
        // insert("AUD", "JPY", 90);
        // insert("GBP", "JPY", 150);
        // insert("JPY", "INR", 0.6);
        //
        // insert("USD", "EUR", 1.0/1.2);
        // insert("GBP", "USD", 1.0/0.75);
        // insert("AUD", "GBP", 1.0/1.7);
        // insert("JPY", "AUD", 1.0/90);
        // insert("JPY", "GBP", 1.0/150);
        // insert("INR", "JPY", 1.0/0.6);
    }

    private void insert(String src, String dst, double rate) {
        if (mapping.get(src) == null) {
            Map<String, Double> map = new HashMap<String, Double>();
            map.put(dst, rate);
            mapping.put(src, map);
        } else if (mapping.get(src).get(dst) == null) {
            mapping.get(src).put(dst, rate);
        }
    }

    public static void main(String args[]) {
        try {
            double d = new CurrencyConvertor().convert("EUR", 100, "INR");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
 0
Author: mkag, 2020-01-03 05:54:11