我在 Javascript 中有以下代码:
var m1 = 2232.00;
var percent = (10/100);
var total = percent*m1;
alert(total);
问题是变量“total”给了我“223.20000000000002”,它应该是“223.2”,我应该怎么做才能得到正确的值?
我在 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
You can't get the exact value. This is the fundamental problem with floating-point numbers.
You can force a fixed number of decimal numbers with toFixed
:
alert(total.toFixed(2));
However, keep in mind that this will leave trailing zeroes, which you might not want. You can remove them with .replace(/0+$/,'');
If you are trying to display this number, you could convert to a string with toFixed(1). If you do this, keep track of the types because you can't then multiply the string with another number.
If you are going to use it in another computation you could truncate it to one decimal place:
Math.round( total * 10 ) / 10
However, as pointed out by various people, the inexact value is just the way floating point numbers are.
See the questions linked in the comments for more good information.
感谢Dimitry ,我使用以下页面找到了答案:
我决定使用以下类,因为我需要操作的确切值,并且它们与货币操作有关:
运算符“*”和“/”并不总是完美地工作,例如:
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( ... ) :
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
这可以通过一个名为decimal.js的外部库来很好地完成,该库为 JavaScript提供了一种Decimal
类型。它也可用于 npm 上的 Node。下面是一个使用 decimal.js 复制来自gustavomanolo的原始示例的示例。
// 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>
total.toFixed(2)
may help. But note that the total
variable be will typecasted into a string.
这是浮点数乘法的解决方案。这很简单,但对我有用。你可以用这个函数计算出数字有多少位小数。
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 = total.toFixed(decimalPlaces(a)+decimalPlaces(b));
a,b 是你的号码
我最终得到了以下解决方案:
function decimalmultiply(a, b) {
return parseFloat((a * b).toFixed(12));
}
10.50*30.45=319.72499999999997
decimalmultiply(10.50,30.45)=319.725
此方法返回一个数字,而不是字符串,不截断有效小数(最多 12 位)。
试试看嘛
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
我找到了一个非常简单的解决方案。当*
涉及十进制数时,运算符有点坏,但/
运算符不是。乘法可以很容易地转换为除法,因为 a • b = a / (1/b)
function times(a, b) { return a/(1/b) }
只需替换percent * m1
为times(percent, m1)
.
更新:它并不总是有效。
如果您使用的是 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>
我希望这会有所帮助......我花了一段时间才到达那里,但它有点奏效。
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;
};