js浮動小数点演算の精度問題を解決します.

25353 ワード

javascriptで演算すると浮動小数点の問題がよく発生します.結果が正確ではない例:0.1 + 0.2 = 0.30000000000000004完全デモ及び解決案は以下の通りである.

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>demotitle>
    <style>
      .num-tags,
      .total-tag {
        text-align: center;
      }
      i {
        font-style: normal;
      }
      #totalTag {
        color: red;
      }
    style>
  head>
  <body>
    <div class="num-tags">
      <label for="moneys1">  1:label>
      <input type="text" class="moneys" value="" onkeyup="checkInput(this)" onblur="checkNum(this)" />
      <label for="moneys2">  2:label>
      <input type="text" class="moneys" value="" onkeyup="checkInput(this)" onblur="checkNum(this)" />
      <button type="button" id="calculates">  button>
    div>
    <div class="total-tag"><i>i><span id="totalTag">span>div>

    <script>
      document.getElementById('calculates').onclick = function () {
        var countSum = 0
        var nums = document.querySelectorAll('.moneys')
        for (var i = nums.length; i--; ) {
          //       ,        
          countSum = formatNum((countSum += parseFloat(nums[i].value)), 10)
        }
        //        ,                
        document.getElementById('totalTag').innerText = toDecimal2(countSum)
      }

      function checkInput(_this) {
        if (_this.value != '' && _this.value.substr(0, 1) == '.') {
          _this.value = 0
        }
        if (_this.value == '') {
          _this.value = 0
        }
        _this.value = _this.value.replace(/^0*(0\.|[1-9])/, '$1') //     
        _this.value = _this.value.replace(/[^\d.]/g, '0.00') //        
        _this.value = _this.value.replace(/\.{2,}/g, '.') //       .      
        _this.value = _this.value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
        _this.value = _this.value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3') //         

        if (_this.value.indexOf('.') < 0 && _this.value != '') {
          //       ,             ,         01、02   
          if (_this.value.substr(0, 1) == '0' && _this.value.length == 2) {
            _this.value = _this.value.substr(1, _this.value.length)
          }
        }
        if (!_this.value) {
          _this.value = 0
        }
      }

      function checkNum(_this) {
        //                   .    0
        _this.value.endsWith('.') ? (_this.value += '0') : _this.value
      }

      //       
      function toDecimal2(x) {
        var f = parseFloat(x)
        if (isNaN(f)) {
          return false
        }
        var f = Math.round(x * 100) / 100
        var s = f.toString()
        var rs = s.indexOf('.')
        if (rs < 0) {
          rs = s.length
          s += '.'
        }
        while (s.length <= rs + 2) {
          s += '0'
        }
        return s
      }

      //            10   n   ,               ,      10   n   
      function formatNum(f, digit) {
        var m = Math.pow(10, digit)
        return parseInt(f * m, 10) / m
      }
    script>
  body>
html>