【问题标题】:How to multiply in Javascript? problems with decimals如何在 Javascript 中进行乘法运算?小数问题
【发布时间】:2013-01-07 13:38:57
【问题描述】:

我在 Javascript 中有以下代码:

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

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

【问题讨论】:

标签: javascript decimal multiplication


【解决方案1】:

.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

【讨论】:

  • 注意,.toFixed(n) 的结果是 字符串 不是十进制值...所以使用 ++= 将连接,而不是添加到变量中跨度>
【解决方案2】:

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

您可以使用toFixed 强制使用固定数量的十进制数:

alert(total.toFixed(2));

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

【讨论】:

  • 您可能还想在.replace(/0+$/, '') 之后使用.replace(/.$/, '') 来删除任何尾随小数点(如果有的话)。
  • .replace(/.$/, '') 不起作用尝试使用.replace(/\.$/, '')
【解决方案3】:

如果你想显示这个数字,你可以用toFixed(1) 转换成一个字符串。如果您这样做,请跟踪类型,因为您不能将字符串与另一个数字相乘。

如果你打算在另一个计算中使用它,你可以将它截断到小数点后一位:

Math.round( total * 10 ) / 10

但是,正如很多人指出的那样,不精确的值就是浮点数的方式。

有关更多有用信息,请参阅 cmets 中链接的问题。

【讨论】:

  • 事实是我不需要将此值转换为字符串,因为我需要使用变量“total”与另一个相乘。
  • 您可以按原样安全地进行操作。这也是 JS、MSVC++ 浮点数或双精度浮点数的方式。
【解决方案4】:

感谢Dimitry,我使用以下页面找到了答案:

Floating-point cheat sheet for JavaScript

我决定使用以下分类,因为我需要操作的确切值并且它们与货币操作有关:

【讨论】:

【解决方案5】:

运算符“*”和“/”并不总是完美的,例如:

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

【讨论】:

    【解决方案6】:

    这可以通过一个名为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>

    【讨论】:

      【解决方案7】:

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

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

      【讨论】:

      【解决方案8】:

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

      【解决方案9】:

      试试吧

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

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

      【讨论】:

      • 它不能正常工作。取 x = 0.041
      【解决方案10】:

      我最终得到了以下解决方案:

      function decimalmultiply(a, b) {
          return parseFloat((a * b).toFixed(12));
      }
      
      10.50*30.45=319.72499999999997
      decimalmultiply(10.50,30.45)=319.725
      

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

      【讨论】:

        【解决方案11】:

        你可以的

        var total = +(percent*m1).toPrecision(15);
        
        223.2 === total;          // true
        223.2 === 0.1*2232.00;    // false
        

        【讨论】:

          【解决方案12】:

          如果您使用的是 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

          用下面这个 sn-p 自己试试吧。

           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>

          【讨论】:

            【解决方案13】:

            我找到了一个非常简单的解决方案。 * 运算符在处理十进制数时有点破旧,但 / 运算符则不然。乘法可以很容易地转化为除法,因为 a • b = a / (1/b)

            function times(a, b) { return a/(1/b) }
            

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

            更新:它并不总是有效。

            【讨论】:

            • 它不起作用:32.09 * 100 = 3209.0000000000005 100 / (1 / 32.09) = 3209.0000000000005
            【解决方案14】:

            我希望这会有所帮助……我花了一些时间才到达那里,但它确实起到了作用。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-05-22
              • 1970-01-01
              • 2018-07-14
              • 2019-07-07
              • 1970-01-01
              相关资源
              最近更新 更多