package com.goafanti.evaluation.controller; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.validation.Valid; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.Assert; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.goafanti.common.bo.Result; import com.goafanti.common.constant.ErrorConstants; import com.goafanti.common.controller.BaseApiController; import com.goafanti.common.model.DistrictGlossory; import com.goafanti.common.model.IndustryCategory; import com.goafanti.common.model.ValueEvaluation; import com.goafanti.common.service.IndustryCategoryService; import com.goafanti.common.service.SysDictService; import com.goafanti.common.utils.LoggerUtils; import com.goafanti.core.shiro.token.TokenManager; import com.goafanti.dataGlossory.service.DistrictGlossoryService; import com.goafanti.evaluation.bo.ForecastIncome; import com.goafanti.evaluation.bo.Step1; import com.goafanti.evaluation.bo.Step2; import com.goafanti.evaluation.bo.Step3; import com.goafanti.evaluation.bo.Step4; import com.goafanti.evaluation.bo.Step5; import com.goafanti.evaluation.bo.Step6; import com.goafanti.evaluation.bo.Step7; import com.goafanti.evaluation.bo.YearIncome; import com.goafanti.evaluation.enums.ProfitRate; import com.goafanti.evaluation.service.ValueEvaluationService; @RestController @RequestMapping(value = "/api/user/evaluate") public class EvaluationController extends BaseApiController { private static final Logger logger = LoggerFactory.getLogger(EvaluationController.class); private static final MathContext DEFAULT_PRECISION = new MathContext(4, RoundingMode.HALF_UP); private static final String STEP1 = "0"; private static final String STEP2 = "1"; private static final String STEP3 = "2"; private static final String STEP4 = "3"; private static final String STEP5 = "4"; private static final String STEP6 = "5"; private static final String STEP7 = "6"; private static final Integer[] SCORES = new Integer[] { 100, 80, 60, 40, 20, 0 }; private static final Integer[] DISCOUNT_SCORES = new Integer[] { 1, 2, 3, 4, 5 }; private static final BigDecimal MIN_RATE = new BigDecimal(2); private static final BigDecimal MAX_RATE = new BigDecimal(6); private static final BigDecimal HUNDRED = new BigDecimal(100); private static final BigDecimal PERCENTAGE = new BigDecimal(0.01, DEFAULT_PRECISION); @Autowired ValueEvaluationService valueEvaluationService; @Autowired private DistrictGlossoryService districtGlossoryService; @Autowired private IndustryCategoryService industryCategoryService; @Autowired private SysDictService sysDictService; @RequestMapping(value = "/create", method = RequestMethod.GET) public Result create() { ValueEvaluation ve = new ValueEvaluation(); ve.setUid(TokenManager.getUserId()); ve.setStep(0); ve.setValue(0l); ve.setLog("{}"); valueEvaluationService.insert(ve); return new Result(ve.getId().toString()); } @RequestMapping(value = "/list", method = RequestMethod.GET) public Result list(String pageNo, String pageSize) { return new Result().data(valueEvaluationService.list(handlePageNo(pageNo), handlePageSize(pageSize))); } @RequestMapping(value = "/info/{id}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8") public Result info(@PathVariable String id) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id)); Assert.notNull(ve, ErrorConstants.EVALUATE_ID); Map res = new HashMap<>(); res.put("name", ve.getName()); res.put("step", ve.getStep()); res.put("value", ve.getValue()); res.put("steps", JSON.parse(ve.getLog())); return new Result().data(res); } @RequestMapping(value = "/remove", method = RequestMethod.POST) public Result remove(String ids) { Assert.isTrue(StringUtils.isNotBlank(ids), ErrorConstants.EVALUATE_PARAM); Result res = new Result(); List idList = new ArrayList<>(); String[] idArr = ids.split(","); for (String id : idArr) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_PARAM); idList.add(Long.valueOf(id)); } res.data(valueEvaluationService.deleteMySteps(idList)); return res; } @RequestMapping(value = "/step1", method = RequestMethod.POST) public Result step1(String id, @Valid Step1 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } updateSteps(data, 1, "0", res, id); return res; } @RequestMapping(value = "/step2", method = RequestMethod.POST) public Result step2(String id, @Valid Step2 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } updateSteps(data, 2, STEP2, res, id); return res; } @RequestMapping(value = "/step3", method = RequestMethod.POST) public Result step3(String id, @Valid Step3 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } updateSteps(data, 3, STEP3, res, id); return res; } @RequestMapping(value = "/step4", method = RequestMethod.POST) public Result step4(String id, String hasIncome, String incomes) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); Step4 step = new Step4(); try { step.setHasIncome(Integer.valueOf(hasIncome)); if (step.getHasIncome().equals(2)) { List ja = JSON.parseArray(incomes, YearIncome.class); if (ja.size() != 3) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } else { step.setIncomes(ja); } } } catch (Exception e) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } if (res.getError().isEmpty()) { updateSteps(step, 4, STEP4, res, id); } return res; } @RequestMapping(value = "/step5", method = RequestMethod.POST) public Result step5(String id, String type, String forecastIncomes) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); Step5 step = new Step5(); try { step.setType(Integer.valueOf(type)); List ja = JSON.parseArray(forecastIncomes, ForecastIncome.class); if (ja.size() != 3) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } else { step.setForecastIncomes(ja); } } catch (Exception e) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } if (res.getError().isEmpty()) { updateSteps(step, 5, STEP5, res, id); } return res; } @RequestMapping(value = "/step5/{id}", method = RequestMethod.GET) public Result step5Info(@PathVariable String id) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id)); try { JSONObject jo = JSON.parseObject(ve.getLog()); Step4 step4 = ((JSON) jo.get(STEP4)).toJavaObject(Step4.class); if (step4.getHasIncome().equals(2)) { Step1 step1 = ((JSON) jo.get(STEP1)).toJavaObject(Step1.class); res.data(calcForecastIncome(step4.getIncomes(), getIndustryCategoryValue(step1))); } } catch (Exception e) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } return res; } @RequestMapping(value = "/step6", method = RequestMethod.POST) public Result step6(String id, @Valid Step6 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } updateSteps(data, 6, STEP6, res, id); return res; } @RequestMapping(value = "/step7", method = RequestMethod.POST) public Result step7(String id, @Valid Step7 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } updateSteps(data, 7, STEP7, res, id); return res; } @RequestMapping(value = "/calc/{id}", method = RequestMethod.GET) public Result calc(@PathVariable String id) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id)); if (ve == null || ve.getStep() < 7) { res.error(buildError(ErrorConstants.EVALUATE_ID)); } else { Long value = calcValue(ve, new HashMap<>()); res.data(value); ValueEvaluation upt = new ValueEvaluation(); upt.setId(ve.getId()); upt.setValue(value); valueEvaluationService.update(upt); } return res; } @RequestMapping(value = "/report/{id}", method = RequestMethod.GET) public Result report(@PathVariable String id) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id)); if (ve == null || ve.getStep() < 7) { res.error(buildError(ErrorConstants.EVALUATE_ID)); } else { Map map = new HashMap<>(); calcValue(ve, map); res.data(map); } return res; } private Long calcValue(ValueEvaluation ve, Map result) { JSONObject log = JSON.parseObject(ve.getLog()); Step1 step1 = ((JSON) log.get(STEP1)).toJavaObject(Step1.class); Step2 step2 = ((JSON) log.get(STEP2)).toJavaObject(Step2.class); Step3 step3 = ((JSON) log.get(STEP3)).toJavaObject(Step3.class); Step5 step5 = ((JSON) log.get(STEP5)).toJavaObject(Step5.class); Step6 step6 = ((JSON) log.get(STEP6)).toJavaObject(Step6.class); Step7 step7 = ((JSON) log.get(STEP7)).toJavaObject(Step7.class); Integer timeLeft = step1.getTimeLeft(); timeLeft = timeLeft < 3 ? 3 : timeLeft > 10 ? 10 : timeLeft; // 剩余经济寿命最低3,最大10年 Map subs = getIndustryCates(step1.getIndustry()); Map provinces = getProvinces(); result.put("subIndustries", Stream.of(step1.getSubIndustry().split(",")).map(it -> { return subs.get(Integer.valueOf(it)).getName(); }).collect(Collectors.joining(","))); result.put("transferArea", Stream.of(step1.getTransferArea().split(",")).map(it -> { return it.equals("0") ? "中国全境" : provinces.get(Integer.valueOf(it)).getName(); }).collect(Collectors.joining(","))); result.put("industry", industryCategoryService.list(0).stream().filter(it -> { return it.getId().equals(step1.getIndustry()); }).findFirst().get().getName()); BigDecimal industryAverageRate = getIndustryCategoryValue(step1, subs); List userForecast = step5.getForecastIncomes().stream().map(fc -> { return fc.getIncome(); }).collect(Collectors.toList()); List sysForecast = calcSysForecast(userForecast, industryAverageRate, timeLeft); calcUserForecast(userForecast, timeLeft); List measuredForecast = calcMeasuredForecast(userForecast, sysForecast); Map profitScores = getProfitScores(step2, step3); Map discountRates = getDiscountRates(step7); BigDecimal profitRate = calcProfitRate(profitScores, step1.getIndustry()); BigDecimal governmentLoanRoR = new BigDecimal(sysDictService.getValue("government_loan_ror"), MathContext.DECIMAL32); BigDecimal taxRate = new BigDecimal(step6.getTaxRate()); BigDecimal discountRate = calcDiscountRate(discountRates, taxRate, governmentLoanRoR); result.put("userForecast", userForecast); result.put("sysForecast", sysForecast); result.put("measuredForecast", measuredForecast); result.put("profitRate", profitRate); result.put("governmentLoanRoR", governmentLoanRoR); result.put("industryAverageRate", industryAverageRate); result.put("discountRate", discountRate); result.put("benchmarkDate", step1.getBenchmarkDate()); result.put("timeLeft", timeLeft); result.put("name", step1.getName()); Long value = calcTotal(measuredForecast, profitRate, discountRate, result); result.put("value", value); result.put("log", log); return value; } private Long calcTotal(List measuredForecast, BigDecimal profitRate, BigDecimal discountRate, Map result) { List profitList = new ArrayList<>(); BigDecimal total = BigDecimal.ZERO; BigDecimal incomeDiscount = BigDecimal.ZERO; double discountTerm = 0.5; int index = 0; BigDecimal discountFactor = BigDecimal.ZERO; for (Long val : measuredForecast) { incomeDiscount = new BigDecimal(val).multiply(profitRate); profitList.add(incomeDiscount.longValue()); discountFactor = BigDecimal.ONE.divide(BigDecimal.ONE.add(discountRate), 4, RoundingMode.FLOOR); discountTerm += index; double pow = Math.pow(discountFactor.doubleValue(), discountTerm); total = total.add(incomeDiscount.multiply(new BigDecimal(pow))); index++; } result.put("profitList", profitList); // 收入分成额 return total.longValue(); } private BigDecimal calcDiscountRate(Map discountRates, BigDecimal taxRate, BigDecimal governmentLoanRoR) { BigDecimal discountRate = new BigDecimal(discountRates.get("capital")) .add(new BigDecimal(discountRates.get("management"))).add(new BigDecimal(discountRates.get("market"))) .add(new BigDecimal(discountRates.get("political"))) .add(new BigDecimal(discountRates.get("technical"))); discountRate = discountRate.add(governmentLoanRoR).divide(HUNDRED.subtract(taxRate), 4, RoundingMode.FLOOR); double rate = discountRate.doubleValue(); rate = rate > 0.3 ? 0.3 : rate < 0.17 ? 0.17 : rate; discountRate = new BigDecimal(rate, DEFAULT_PRECISION); return discountRate; } private Map getDiscountRates(Step7 step7) { Map profitScores = new HashMap<>(); profitScores.put("capital", getDiscountScore(step7.getCapital()));// 资金风险 profitScores.put("management", getDiscountScore(step7.getManagement()));// 管理风险 profitScores.put("market", getDiscountScore(step7.getMarket()));// 市场风险 profitScores.put("political", getDiscountScore(step7.getPolitical()));// 政策风险 profitScores.put("technical", getDiscountScore(step7.getTechnical()));// 技术风险 return profitScores; } private BigDecimal calcProfitRate(Map profitScores, Integer industry) { BigDecimal legalFactor = new BigDecimal(0.2, DEFAULT_PRECISION); BigDecimal techFactor = new BigDecimal(0.6, DEFAULT_PRECISION); BigDecimal fundFactor = legalFactor; BigDecimal profitRate = new BigDecimal(profitScores.get("confidentiality")).multiply(legalFactor) .multiply(new BigDecimal(0.4, DEFAULT_PRECISION)); profitRate = profitRate.add(new BigDecimal(profitScores.get("legalStatus")).multiply(legalFactor) .multiply(new BigDecimal(0.3, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("decidability")).multiply(legalFactor) .multiply(new BigDecimal(0.3, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("prospect")).multiply(techFactor) .multiply(new BigDecimal(0.1, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("alternatives")).multiply(techFactor) .multiply(new BigDecimal(0.2, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("progressiveness")).multiply(techFactor) .multiply(new BigDecimal(0.2, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("innovativeness")).multiply(techFactor) .multiply(new BigDecimal(0.1, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("ripeness")).multiply(techFactor) .multiply(new BigDecimal(0.2, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("rangeOfApplication")).multiply(techFactor) .multiply(new BigDecimal(0.1, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("defensive")).multiply(techFactor) .multiply(new BigDecimal(0.1, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("supplyAndDemand")).multiply(fundFactor) .multiply(new BigDecimal(0.6, DEFAULT_PRECISION))); profitRate = profitRate.add(new BigDecimal(profitScores.get("profitability")).multiply(fundFactor) .multiply(new BigDecimal(0.4, DEFAULT_PRECISION))); BigDecimal minRate = MIN_RATE; BigDecimal maxRate = MAX_RATE; if (ProfitRate.containsType(industry)) { ProfitRate pr = ProfitRate.getProfitRate(industry); minRate = new BigDecimal(pr.getMinRate()); maxRate = new BigDecimal(pr.getMaxRate()); } profitRate = maxRate.subtract(minRate).multiply(profitRate.multiply(PERCENTAGE)).add(minRate) .multiply(PERCENTAGE).setScale(4, RoundingMode.FLOOR); return profitRate; } private Map getProfitScores(Step2 step2, Step3 step3) { // 法律因素权重 20% Map profitScores = new HashMap<>(); profitScores.put("legalStatus", getScore(step2.getLegalStatus()));// 法律状态 profitScores.put("confidentiality", getScore(step2.getConfidentiality()));// 保密性 profitScores.put("decidability", getScore(step2.getDecidability()));// 侵权可判定性 // 技术因素权重 60% profitScores.put("prospect", getScore(step3.getProspect()));// 领域前景 profitScores.put("alternatives", getScore(step3.getAlternatives()));// 可替代性 profitScores.put("progressiveness", getScore(step3.getProgressiveness()));// 先进性 profitScores.put("innovativeness", getScore(step3.getInnovativeness()));// 创新性 profitScores.put("ripeness", getScore(step3.getRipeness()));// 成熟度 profitScores.put("rangeOfApplication", getScore(step3.getRangeOfApplication()));// 应用范围 profitScores.put("defensive", getScore(step3.getDefensive()));// 应用范围 // 经济因素 20% profitScores.put("supplyAndDemand", getScore(step3.getSupplyAndDemand()));// 供求关系 profitScores.put("profitability", getScore(step3.getProfitability()));// 独立获利能力 return profitScores; } private Integer getScore(int option) { int idx = option - 1; idx = idx < 0 ? 0 : idx >= SCORES.length ? SCORES.length - 1 : idx; return SCORES[idx]; } private Integer getDiscountScore(int option) { int idx = option - 1; idx = idx < 0 ? 0 : idx >= DISCOUNT_SCORES.length ? DISCOUNT_SCORES.length - 1 : idx; return DISCOUNT_SCORES[idx]; } private void calcUserForecast(List userForecast, Integer timeLeft) { Assert.isTrue(userForecast.get(0) > 0 && userForecast.get(1) > 0, ErrorConstants.EVALUATE_PARAM); BigDecimal second = new BigDecimal(userForecast.get(1)); BigDecimal lastYear = new BigDecimal(userForecast.get(2)); BigDecimal rate = lastYear.divide(second, 2, RoundingMode.HALF_UP) .subtract(BigDecimal.ONE).add(second .divide(new BigDecimal(userForecast.get(0)), 2, RoundingMode.HALF_UP).subtract(BigDecimal.ONE)) .divide(new BigDecimal(2)); BigDecimal step = new BigDecimal(0.1, DEFAULT_PRECISION); int size = userForecast.size(); for (int i = size; i < timeLeft; i++) { if (i < 6) { lastYear = lastYear.multiply( BigDecimal.ONE.add(rate.multiply(rate.subtract(step.multiply(new BigDecimal(i - size)))))); } userForecast.add(lastYear.longValue()); } } private List calcSysForecast(List userForecast, BigDecimal industryAverageRate, Integer timeLeft) { List sysForecast = new ArrayList<>(); BigDecimal lastYear = BigDecimal.ZERO; BigDecimal step = new BigDecimal(0.1, DEFAULT_PRECISION); industryAverageRate = industryAverageRate.multiply(PERCENTAGE); for (int i = 0; i < timeLeft; i++) { if (i == 0) { lastYear = new BigDecimal(userForecast.get(0)).multiply(new BigDecimal(0.9, DEFAULT_PRECISION)); } else if (i < 6) { lastYear = lastYear.multiply(BigDecimal.ONE.add( industryAverageRate.multiply(BigDecimal.ONE.subtract(step.multiply(new BigDecimal(i - 1)))))); } sysForecast.add(lastYear.longValue()); } return sysForecast; } private List calcMeasuredForecast(List userForecast, List sysForecast) { List measuredForecast = new ArrayList<>(); for (int i = 0; i < sysForecast.size(); i++) { measuredForecast.add((userForecast.get(i) + sysForecast.get(i)) >> 1); } return measuredForecast; } private void updateSteps(Object step, Integer nextStep, String key, Result res, String id) { ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id)); Assert.notNull(ve, ErrorConstants.EVALUATE_ID); ve.setStep(Math.max(nextStep, ve.getStep())); if (nextStep == 1) { ve.setName(((Step1) step).getName()); } ve.setValue(0l); JSONObject jo = JSON.parseObject(ve.getLog()); jo.put(key, step); ve.setLog(jo.toJSONString()); res.data(valueEvaluationService.update(ve)); } private boolean handleBindingError(Result res, BindingResult bindingResult) { if (bindingResult.hasErrors()) { LoggerUtils.debug(logger, "参数错误:[%s], [%s], [%s]", bindingResult.getFieldError().getDefaultMessage(), bindingResult.getFieldError().getField(), bindingResult.getFieldError().getRejectedValue()); res.getError().add(buildError(ErrorConstants.EVALUATE_PARAM)); return true; } return false; } private BigDecimal getIndustryCategoryValue(Step1 step1) { return getIndustryCategoryValue(step1, getIndustryCates(step1.getIndustry())); } private Map getIndustryCates(Integer pid) { return industryCategoryService.list(pid).stream() .collect(Collectors.toMap(IndustryCategory::getId, (it) -> it)); } private Map getProvinces() { return districtGlossoryService.list(0).stream().collect(Collectors.toMap(DistrictGlossory::getId, (it) -> it)); } private BigDecimal getIndustryCategoryValue(Step1 step1, Map cates) { List subIds = Stream.of(step1.getSubIndustry().split(",")).map(it -> { return Integer.valueOf(it); }).collect(Collectors.toList()); BigDecimal average = BigDecimal.ZERO; int count = 0; for (Integer id : subIds) { if (cates.containsKey(id)) { average = average.add(cates.get(id).getValue()); count++; } } return average.divide(new BigDecimal(count == 0 ? 1 : count), 2, RoundingMode.HALF_UP); } private Long[] calcForecastIncome(List incomes, BigDecimal growth) { BigDecimal useGrowth = growth.multiply(PERCENTAGE); BigDecimal base = new BigDecimal(incomes.get(0).getIncome()); if (!incomes.get(1).getIncome().equals(0)) { useGrowth = base.divide(new BigDecimal(incomes.get(1).getIncome()), 2, RoundingMode.CEILING) .subtract(BigDecimal.ONE); } Long[] res = new Long[3]; BigDecimal one = base.multiply(useGrowth.add(BigDecimal.ONE)); useGrowth = useGrowth.multiply(new BigDecimal(0.9, DEFAULT_PRECISION)); BigDecimal two = one.multiply(useGrowth.add(BigDecimal.ONE)); useGrowth = useGrowth.multiply(new BigDecimal(0.8, DEFAULT_PRECISION)); res[2] = two.multiply(useGrowth.add(BigDecimal.ONE)).longValue(); res[0] = one.longValue(); res[1] = two.longValue(); return res; } }