如何在Javascript中相乘?小数问题

时间:2013-01-23 22:22:37

标签: javascript decimal multiplying

我在Javascript中有以下代码:

var m1 = 2232.00;
var percent = (10/100);
var total = percent*m1;
alert(total);

问题是变量“total”给了我“223.20000000000002”,它应该是“223.2”,我该怎么做才能得到正确的值?

14 个答案:

答案 0 :(得分:19)

.toFixed()是最好的解决方案。点后只保留两位数。

Exp 1:

var value = 3.666;
value.toFixed(2); //Output : 3.67

Exp 2:

var value = 3.0000;
value.toFixed(2); //Output : 3.00

答案 1 :(得分:7)

您无法获得确切的值。这是浮点数的基本问题。

您可以使用toFixed

强制使用固定数量的十进制数字
alert(total.toFixed(2));

但是,请记住,这将留下您可能不想要的尾随零。您可以使用.replace(/0+$/,'');

删除它们

答案 2 :(得分:4)

如果您尝试显示此号码,则可以转换为toFixed(1)的字符串。如果这样做,请跟踪类型,因为您不能将该字符串与另一个数字相乘。

如果您打算在另一个计算中使用它,可以将其截断为一个小数位:

Math.round( total * 10 ) / 10

然而,正如各位人士所指出的,不精确的价值只是浮点数的方式。

请参阅评论中链接的问题以获取更多有用的信息。

答案 3 :(得分:4)

由于Dimitry

,我使用以下页面找到了答案

Floating-point cheat sheet for JavaScript

我决定使用以下条款,因为我需要操作的确切值,并且它们与资金操作有关:

答案 4 :(得分:3)

使用名为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>
&#13;
&#13;
&#13;

答案 5 :(得分:2)

total.toFixed(2)可能有所帮助。但请注意,total变量将被转换为字符串。

答案 6 :(得分:2)

这是一个解决浮点数乘法的解决方案。这很简单但对我有用。你可以计算出这个函数有多少小数。

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是您的数字

答案 7 :(得分:1)

试试

var x = 0.07;
console.log((x+1)*100 - 100);

现在,将x的值替换为其他值 ; - )

答案 8 :(得分:1)

运算符“ *”和“ /”不能总是正常运行,例如:

32.09 * 100 = 3209.0000000000005
100 / (1 / 32.09) = 3209.0000000000005

解决方案:

一种解决方案,最简单的十进制方法是使用.toFixed(2),其中“ 2”是所需的小数位数。但是您必须考虑到此返回值会返回一个字符串,并且会四舍五入该值。

45.6789.toFixed(2) —> "45.68" as String

最完整的其他选项是使用.toLocaleString,它可以将数字正确转换为所需的国家/地区代码。您可以设置一对参数以将小数值始终固定为2。这还会返回一个String:

(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

答案 9 :(得分:0)

你可以做到

var total = +(percent*m1).toPrecision(15);

223.2 === total;          // true
223.2 === 0.1*2232.00;    // false

答案 10 :(得分:0)

如果您使用的是Angular,我为此制作了一个组件。

使用凉亭安装

bower install angular-floating-point --save

用法

var pretty = floatingPoint.makePretty(6.1*6);
  

这是一个演示 - &gt; https://mattspaulding.github.io/angular-floating-point
  这是源 - &gt; https://github.com/mattspaulding/angular-floating-point

请使用下面的代码片段自行尝试。

&#13;
&#13;
 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();

    });
 
&#13;
<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>
&#13;
&#13;
&#13;

答案 11 :(得分:0)

我找到了一个非常简单的解决方案。对于十进制数字,*运算符有点不完整,但/运算符不是。由于a•b = a /(1 / b)

,乘法可以很容易地转换为除法
function times(a, b) { return a/(1/b) }

只需将percent * m1替换为times(percent, m1)

更新:它不会一直有效。

答案 12 :(得分:0)

我得到了以下解决方案:

function decimalmultiply(a, b) {
    return parseFloat((a * b).toFixed(12));
}

10.50*30.45=319.72499999999997
decimalmultiply(10.50,30.45)=319.725

此方法返回一个数字,而不是一个字符串,而不会截断有效的小数(最多12个)。

答案 13 :(得分:0)

我希望这会有所帮助...我花了一段时间才到达那里,但这确实可以解决问题。

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;
};