我已经获得了一份用Java编写的作业。
我们将开发一种货币转换应用程序,该应用程序将询问他们要转换的货币,所述货币的金额以及他们希望转换成的货币。
该说明指出,我们应包括4种货币之间的相互转换。
我很早就完成了作业,然后去给我的教授看书,她注意到了几个问题。她喜欢代码的组织和清晰性,但她认为我可以将其缩小一点,并以十进制精度解决我遇到的问题。
关于简化它,她的主要论点是我有7个常数来保持汇率。我为此感到非常自豪,因为对于每种可能的组合,7个比率比12个单独的比率短很多。代码在下面。
// 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
我的方法论背后的思考过程是将一切都转换为美元,然后再从美元转换为目标货币。我不确定如何进一步压缩它,因此这就是我遇到的问题之一。
我遇到的主要问题是精度。由于该课程主要基于商业数学,因此该程序通常用于转换数百万/数十亿货币。我知道double已经有自己的精度继承问题,但是我不确定要使用其他哪些数据类型。我遇到过BigDecimal,在发布此内容后,我将对其进行研究。
据我了解,汇率中的小数点位数将直接影响结果的精度。价格右侧的数字越多;更好。我是否应该养成包含大量小数点的习惯,以致很难出现精度问题?或者使用BigDecimal通常可以解决问题。
我考虑过放弃使用double并改用int;因此,我将拥有500个整数而不是5.00的两倍。但目前,我不确定进行的“适当”方法。
所以我来问你好人:D
我很高兴学到尽可能多的知识,感谢您的协助。
谢谢
更新: 我花了一些时间检查BigDecimal,然后它开始工作了。除了我现在的偏离量为1到10(可能非常大的数字会更多,但是我使用不同的数字进行的测试没有超过5次)。
在测试中,我将18765432.00日元转换为美元,汇率为1日元= 0.008907美元。根据我当时用来验证的网站,以美元计算的结果应该是879,701.24美元;但我的程序却能获得879,703.70美元。甚至我的科学计算器也得到了与Java程序相同的东西。
答案 0 :(得分:0)
继续使用BigDecimal实施方法,就像使用BigDecimal一样,您将不会失去任何精度,但是如果您处理更大的数字,则使用DoubleDecimal可能会有损失的可能性。
请通过下面的stackoverflow链接获取有关BigDecimal的更多信息: Double vs. BigDecimal?
您处在正确的轨道上,继续摇摆并愉快地学习。
答案 1 :(得分:0)
这是另一种实现方式:
给出如下货币汇率列表:
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);**```
==============
包装测试;
导入java.util。*;
公共类CurrencyConvertor { 私人地图>映射=新的HashMap>(); 私有布尔值bInit = false; 私人布尔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();
}
}
}