如何在Javascript中乘法?小数的问题
How to multiply in Javascript? problems with decimals
我在Javascript中有以下代码:
var m1 = 2232.00;
var percent = (10/100);
var total = percent*m1;
alert(total);
问题是变量"total"给了我"223.20000000000002",它应该是"223.2",我应该怎么做才能得到正确的值?
.toFixed() 是最好的解决方案。它将只保留点后的两位数字。
经验 1:
var value = 3.666;
value.toFixed(2); //Output : 3.67
经验 2:
var value = 3.0000;
value.toFixed(2); //Output : 3.00
您无法获得确切的值。这是浮点数的根本问题。
您可以使用toFixed
强制使用固定数量的十进制数:
alert(total.toFixed(2));
但是,请记住,这将留下尾随零,您可能不希望这样做。您可以使用.replace(/0+$/,'');
删除它们
如果你试图显示这个数字,你可以用toFixed(1)转换为一个字符串。如果执行此操作,请跟踪类型,因为无法将字符串与另一个数字相乘。
如果你打算在另一个计算中使用它,你可以把它截断到一个小数点后一位:
Math.round( total * 10 ) / 10
但是,正如各种人指出的那样,不精确的值只是浮点数的方式。
请参阅评论中链接的问题以获取更多相关信息。
我使用以下页面找到了答案,感谢 Dimitry:
JavaScript 的浮点备忘单
我决定使用以下分类,因为我需要操作的确切值,并且它们与货币操作相关:
- https://github.com/MikeMcl/big.js
- https://github.com/MikeMcl/bignumber.js/
运算符"*"和"/"并不总是完美工作,例如:
32.09 * 100 = 3209.0000000000005
100 / (1 / 32.09) = 3209.0000000000005
溶液:
使用小数的一个解决方案,即简单的解决方案是使用 .toFixed(2),其中"2"是您想要的十进制位数。但是你必须考虑到这返回一个字符串,它会舍入值。
45.6789.toFixed(2) —> "45.68" as String
另一个最完整的选项是使用 .toLocaleString,它将数字正确转换为您想要的国家/地区代码。您可以设置一对参数以将小数值始终固定为 2。这还会返回一个字符串:
(654.3453).toLocaleString(
'en-US',
{minimumFractionDigits: 2, maximumFractionDigits: 2},
) —> "654.35" as String
如果你需要它作为一个数字,你可以把它包装成数字(...):
Number((654.3453).toLocaleString(
'en-US',
{minimumFractionDigits: 2, maximumFractionDigits: 2},
)) —> 654.35 as Number
如果只需要没有十进制数,请使用此方法之一来确保结果没有小数。
Math.trunc(32.09); —> 32 as Number
(32.09).toFixed(0); —> “32” as String
32.09 | 0; —> 32 as Number
total.toFixed(2)
可能会有所帮助。但请注意,total
变量 be 将类型转换为字符串。
可以通过一个名为decimal的外部库来完成.js它为JavaScript提供了一个Decimal
类型。它也适用于 npm 上的 Node。下面是一个使用十进制.js复制古斯塔沃马诺洛原始示例的示例。
// Decimal type provided by decimal.js (http://mikemcl.github.io/decimal.js/)
var m1 = new Decimal( 2232.00 );
var percent = new Decimal( 10/100 );
var total = m1.mul(percent);
console.log( 'Total:', total );
<script src="https://cdnjs.cloudflare.com/ajax/libs/decimal.js/7.2.3/decimal.min.js"></script>
我最终得到了以下解决方案:
function decimalmultiply(a, b) {
return parseFloat((a * b).toFixed(12));
}
10.50*30.45=319.72499999999997
decimalmultiply(10.50,30.45)=319.725
此方法返回一个数字,而不是一个字符串,而不截断有效小数(最多 12)。
这是浮点数乘法的解决方法。这很简单,但对我有用。您可以使用此函数计算出数字有多少位小数。
function decimalPlaces(num) {
var match = (''+num).match(/(?:'.('d+))?(?:[eE]([+-]?'d+))?$/);
if (!match) { return 0; }
return Math.max(
0,
// Number of digits right of decimal point.
(match[1] ? match[1].length : 0)
// Adjust for scientific notation.
- (match[2] ? +match[2] : 0));
}
然后对于您的最终答案"总计",您确实这样做
total = total.toFixed(decimalPlaces(a)+decimalPlaces(b));
其中 a,b 是你的数字
试试
吧var x = 0.07;
console.log((x+1)*100 - 100);
现在,将 x 的值替换为其他值;-)
你可以做
var total = +(percent*m1).toPrecision(15);
223.2 === total; // true
223.2 === 0.1*2232.00; // false
如果你使用的是Angular,我为此做了一个组件。
用凉亭安装
bower install angular-floating-point --save
用法
var pretty = floatingPoint.makePretty(6.1*6);
这是一个演示-> https://mattspaulding.github.io/angular-floating-point
这是来源 -> https://github.com/mattspaulding/angular-floating-point
使用下面的此代码段自己尝试一下。
angular.module('myApp', ['floatingPoint'])
.controller('myCtrl', function ($scope, floatingPoint) {
$scope.calculate = function () {
$scope.result =$scope.num0*$scope.num1;
$scope.prettyResult=floatingPoint.makePretty($scope.result)
}
$scope.num0=6.1;
$scope.num1=6;
$scope.calculate();
});
<html>
<head>
<title>My Angular App</title>
<script src='//code.jquery.com/jquery-latest.min.js'></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://rawgit.com/mattspaulding/angular-floating-point/master/dist/angular-floating-point.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div class="row" style="padding-top: 10px;text-align:center">
<label>(try me) ==> </label>
<input ng-model="num0" ng-change="calculate()" style="width:100px; height:30px">
X
<input ng-model="num1" ng-change="calculate()" style="width:100px; height:30px">
</div>
<div class="row" style="padding-top: 50px;">
<div class="col-xs-6">
<label style="float: right;">Ugly calculation:</label>
</div>
<div class="col-xs-6">
<label style="float: left;">{{result}}</label>
</div>
</div>
<div class="row" style="padding-top: 20px;">
<div class="col-xs-6">
<label style="float: right;"><span style="color:blue">Angular Floating Point</span> calculation:</label>
</div>
<div class="col-xs-6">
<label style="float: left;">{{prettyResult}}</label>
</div>
</div>
</body>
我找到了一个非常简单的解决方案。当涉及到十进制数时,*
运算符有点损坏,但/
运算符则不然。乘法可以很容易地转换为除法,因为 a • b = a/(1/b)
function times(a, b) { return a/(1/b) }
只需将percent * m1
替换为times(percent, m1)
即可。
更新:它并非一直有效。
我希望这有帮助...我花了一段时间才到达那里,但它有点成功。
Number.prototype.CountDecimals = function () {
if (Math.floor(this.valueOf()) === this.valueOf())
return 0;
return this.toString().split(".")[1].length || 0;
};
String.prototype.PadRight = function (fullLength, character) {
if (String.isNullOrEmpty(this.toString()) || String.isNullOrEmpty(character))
return this.toString();
var value = this.toString();
while (value.length < fullLength)
value += character;
return value;
};
var Multiply = function () {
var maxNumberOfDecimals = 0;
for (var i = 0; i < arguments.length; i++) {
var decimals = arguments[i].CountDecimals();
if (decimals > maxNumberOfDecimals)
maxNumberOfDecimals=decimals;
}
var results = 1;
for (var j = 0; j < arguments.length; j++) {
var arg = arguments[j];
arg = arg * parseFloat('1'.PadRight(maxNumberOfDecimals + 1, '0'));
results = results * arg;
}
var divisor = parseFloat('1'.PadRight((maxNumberOfDecimals * arguments.length) +1, '0'));
return results / divisor;
};
- 在指令控制器中使用$attrs时出现问题
- 将PHP变量传递给jQuery时遇到问题
- Canvas Html5绘图应用程序,移动画布会导致重大问题
- 参数变量出现ngTable指令问题
- 剑道网格jQuery动画()问题
- 我的jQuery插件参数没有正确启动,遇到了问题
- 货币代码为欧元-金额的格式不应包含小数
- Phonegap-(安卓/iphone)多个图像的图像库出现问题
- TableExport jquery插件:文件名和扩展名问题
- JavaScript Pub/Sub属性访问问题
- JavaScript异步问题
- 如何解决Yii中的页面刷新问题
- Safari(Mac OS)上的jQuery平滑滚动问题
- jqGrid树网格问题
- 小数、逗号和客户端验证的问题
- angularJS 和 JavaScript 数学小数问题
- 使用小数的Javascript操作符问题
- Javascript四舍五入到所需的小数位数问题
- javascript添加会产生奇怪的小数问题
- 如何在Javascript中乘法?小数的问题