Коллеги изучаю документацию по разработке. (конкретно с миксин MONEYUTILSMIXIN, а МЕТОД GETPERCENTAGEPART)
https://academy.terrasoft.ru/documents/technic-sdk/7-13/miksin-moneyutilsmixin
Прошу помощи знающих коллег.
!!результат данного метода получают так.
taxAmount = this.getPercentagePart(totalAmount, discountTax);
тут мне все понятно :)
Мой вопрос почему именно метод GETPERCENTAGEPART в MONEYUTILSMIXIN реализован именно так?
/**
* Calculates percent part of whole value by given percent.
* example:
* amount = 10, percent = 20, result = 2 (2 is 20% of 10).
* @param {Number} amount Total value.
* @param {Number} percent Partial percent .
* @returns {Number}
*/
getPercentagePart: function(amount, percent) {
//Обьявили переменную присвоили ей значение функции
var decimalUtils = this.getDecimalUtils();
// вернули значение переменой как функции в зависимости от переданных параметров
return decimalUtils.evaluate({multiply: [{divide: [percent, 100]}, amount]
});
},
**************************************************************************************
Зачем создали функцию getDecimalUtils и что в ней делают?
Зачем создали функции multiply и divide?
Далее смотрю эти функции getDecimalUtils, multiply и divide.
/**
* Returns {@link Terrasoft.DecimalUtils} instance used to perform numeric computations.
* @private
* @return {Terrasoft.DecimalUtils}
*/
getDecimalUtils: function(config) {
config = config || {};
if (!this.decimalUtils) {
this.decimalUtils = Ext.create("Terrasoft.DecimalUtils");
}
this.decimalUtils.decimalPlaces = config.precision || Terrasoft.data.constants.MONEY_PRECISION;
return this.decimalUtils;
},
/**
* Divide x value by y value.
* @param {Number} x Numerator.
* @param {Number} y Denominator.
* @return {Number} Returns result rounded to current number of decimal places.
*/
divide: function(x, y) {
return this.evaluate({divide: [x, y]});
},
/**
* Multiplies x value by y value.
* @param {Number} x Value.
* @param {Number} y Value.
* @return {Number} Returns result rounded to current number of decimal places.
*/
multiply: function(x, y) {
return this.evaluate({multiply: [x, y]});
},
Зачем создали функцию evaluate которая в свою очередь использует функцию internalEvaluate ?
/**
* Evaluates operations provided in expression.
* @param {Object} expression
* Example:
* to compute expression ((totalAmount * discountTax) / (100 + discountTax)) used expression:
* {divide: [{multiply: [totalAmount, discountTax]}, {add: [100, discountTax]}]}
*
* @return {Number} Returns result rounded to current number of decimal places.
*/
evaluate: function(expression) {
var value = this.internalEvaluate(expression);
return this.prepareValue(value);
}
/**
* Evaluates passed expression.
* @private
* @param expression Expression to evaluate.
* @param [operation] Expression operation (#operations).
* @return {Object} decimal.js value, as result of evaluated expression.
* @throw Terrasoft.InvalidFormatException if expression is incorrect.
*/
internalEvaluate: function(expression, operation) {
var resultItem = null;
if (Ext.isNumber(expression)){
resultItem = new this.decimal(expression);
} else if (Ext.isObject(expression)) {
Terrasoft.each(expression, function(item, operation) {
resultItem = this.internalEvaluate(item, operation);
return false;
}, this);
} else if (Ext.isArray(expression)) {
if (!Ext.isDefined(operation)){
throw new Terrasoft.InvalidFormatException();
}
var resultArray = [];
Terrasoft.each(expression, function(item, index) {
resultArray[index] = this.internalEvaluate(item);
}, this);
resultItem = this.applyOperation(operation, resultArray);
}
if (resultItem === null){
return NaN;
}
return resultItem;
},
Коллеги подскажите почему такая сложная реализация ?
Где можно просветится по такой методологии?
Почему не сделали ??
amount = 10, percent = 20, result = 2 (2 is 20% of 10).
amount * percent / 100 ( 10*20/100 ) = 2
Спасибо, тем кто отзовется, если дадите ссылки на ресурсы почему так программируют буду признателен.
Нравится
Я так понял, что не используем просто формулу
amount * percent / 100 ( 10*20/100 ) = 2
а пользуемся функцией getPercentagePart которая в свою очередь использует модуль DecimalUtils (для избежания ошибок с плавающей точкой) .
Коллеги разработчики террасофт дайте обратную связь я правильно понимаю необходимость такой реализации?
!!Далее пытаюсь понять код модуля DecimalUtils и его методов Divide, Multiplies, evaluate, internalEvaluate, applyOperation !!!
как это позволило избежать ошибок округления?
/**
* Divide x value by y value.
* @param {Number} x Numerator.
* @param {Number} y Denominator.
* @return {Number} Returns result rounded to current number of decimal places.
*/
divide: function(x, y) {
return this.evaluate({divide: [x, y]});
},
/**
* Multiplies x value by y value.
* @param {Number} x Value.
* @param {Number} y Value.
* @return {Number} Returns result rounded to current number of decimal places.
*/
multiply: function(x, y) {
return this.evaluate({multiply: [x, y]});
},
Зачем создали функцию evaluate которая в свою очередь использует функцию internalEvaluate ?
/**
* Evaluates operations provided in expression.
* @param {Object} expression
* Example:
* to compute expression ((totalAmount * discountTax) / (100 + discountTax)) used expression:
* {divide: [{multiply: [totalAmount, discountTax]}, {add: [100, discountTax]}]}
*
* @return {Number} Returns result rounded to current number of decimal places.
*/
evaluate: function(expression) {
var value = this.internalEvaluate(expression);
return this.prepareValue(value);
}
/**
* Evaluates passed expression.
* @private
* @param expression Expression to evaluate.
* @param [operation] Expression operation (#operations).
* @return {Object} decimal.js value, as result of evaluated expression.
* @throw Terrasoft.InvalidFormatException if expression is incorrect.
*/
internalEvaluate: function(expression, operation) {
var resultItem = null;
if (Ext.isNumber(expression)){
resultItem = new this.decimal(expression);
} else if (Ext.isObject(expression)) {
Terrasoft.each(expression, function(item, operation) {
resultItem = this.internalEvaluate(item, operation);
return false;
}, this);
} else if (Ext.isArray(expression)) {
if (!Ext.isDefined(operation)){
throw new Terrasoft.InvalidFormatException();
}
var resultArray = [];
Terrasoft.each(expression, function(item, index) {
resultArray[index] = this.internalEvaluate(item);
}, this);
resultItem = this.applyOperation(operation, resultArray);
}
if (resultItem === null){
return NaN;
}
return resultItem;
},
applyOperation
Такую «магию» действительно используют из-за странностей работы с плавающей запятой. Недавно в другой теме приводил ссылки на статьи.