【问题标题】:Why does toPrecision return a String?为什么 toPrecision 返回一个字符串?
【发布时间】:2010-10-04 23:02:39
【问题描述】:

查看此代码:

function testprecision(){
    var isNotNumber = parseFloat('1.3').toPrecision(6);
    alert(typeof isNotNumber); //=> string
}

我会期待一个数字。如果 'isNotNumber' 应该是一个实数,重铸是解决方案:

alert(typeof parseFloat(isNotNumber)) //=> number

[编辑] 谢谢你的回答。我得出的结论是精度不是那么精确。它可以表示一个数字的总位数,也可以表示小数位数。荷兰(我来自哪里)的大多数人都以“小数位数”的方式考虑精度。 javascript toPrecision 方法涉及第一个表示,所以这很混乱。无论如何,该方法可以引入“错误精度”,对吗?对于我们必须固定的第二个含义,同样如此(返回字符串,错误精度的可能性)。

不管怎样,重新发明轮子是我的主要爱好,我利用我在这里收集的知识尝试构建一个 javascript 浮动对象。也许它对外面的人有用,或者你们中的一个人有更好的想法?

function Float(f,nDec) {
  var Base = this,val;
  setPrecision( nDec || 2 );      
  set( f || 0, nDec || Base.precision );
  Base.set    = set;
  Base.ndec   = setPrecision;
  /** public setprecision 
   *  sets a value for the number of fractional
   *  digits (decimals) you would like getf to 
   *  return. NB: can't be more than 20.
   *  Returns the Float object, so allows method 
   *  chaining
   *  @param {Number} iPrecision
   */
  function setPrecision(iPrecision) {
      var ix = parseInt(iPrecision,10) || 2;
       Base.precision = ix >= 21 ? 20 : ix;
       return Base;
  }
  /** public set
   *  sets the 'internal' value of the object. Returns
   *  the Float object, so allows method chaining
   *  @param {Number} f
   *  @param {Number} ndec
   */
  function set(f,ndec) {
       val =  parseFloat(f) || 0;
       if (ndec) { setPrecision(ndec); }
       Base.val = val;
       return Base;
  }
  /** public get: 
   * return number value (as a float)
   */
  Base.get = function(){
      var ndec = Math.pow(10,Base.precision),
          ival = parseInt(val*ndec,10)/ndec;
      Base.val = ival;
      return Base.val;
  };
  /** public getf 
   *  returns formatted string with precision
   *  (see Base.setPrecision)
   *  if [hx] is supplied, it returns
   *  the float as hexadecimal, otherwise
   *  @param {Boolean} hx
   */
  Base.getf = function(hx){
      var v = Base.val.toFixed(Base.precision);
      return hx ? v.toString(16) : v;
  };
  /** public add
   * adds [f] to the current value (if [f] is a
   * Float, otherwise returns current value)
   * optionally sets a new number of decimals
   * from parameter [ndec]
   * @param {Number} f
   * @param {Number} ndec
   */
  Base.add = function(f,ndec){
      if ( parseFloat(f) || val===0) {
           set(Base.val+parseFloat(f));
           if (ndec) { setPrecision(ndec);}
      }
     return Base.get();
  };
  /** toString 
   *  returns the internal value of the Float object
   *  functions like a getter (supposedly)
   */
  Base.toString = Base.get;
}

用法/示例:

var xf = new Float(); //=> value now 0.0
xf.set(0.86/0.8765,17).add(3.459);
alert(xf+'|'+xf.getf()); //=> 4.440175128351398|4.44017512835139800

【问题讨论】:

    标签: javascript floating-point types numbers


    【解决方案1】:

    问题在于toPrecision的使用。不试一试。

    var isNotNumber = parseFloat('1.3');
    alert(typeof isNotNumber); //=> number
    

    【讨论】:

    • 我完全不明白你的意思!
    【解决方案2】:

    toPrecision 的目的是将Number 的有效十进制 数字截断为指定数量。但是Numbers 的内部表示的数据类型是binary IEEE-754 double。因此,大多数时候不可能精确 返回值存储在 Number 中。由于这种不精确性,返回值将包含无限数量的十进制数字,这将使toPrecision 无效。

    所以这个问题唯一合理的解决方案是返回十进制数字。而目前十进制数字唯一合理的 JS 数据类型是字符串。


    这里有一个例子来说明Numbers 用于十进制数字时的不精确性:

    // the following looks like something with 2 decimal digits:
    var number = 1.6;
    
    // but in fact it's a number with an infinite amount of decimal digits.
    // let's look at the first 30 of them:
    alert(number.toPrecision(30));
    
    // 1.60000000000000008881784197001
    

    【讨论】:

      【解决方案3】:

      来自文档:“将表示 Number 对象的字符串返回到指定的精度。”

      toPrecision() 似乎用于格式化输出,在这种情况下,字符串是最合理的结果。它以不会被进一步操作破坏的形式表示最终输出。

      如果您出于计算原因想要截断一些精度,我倾向于乘以 10^n,其中 n 是我想要保留的数字,从中取一个整数,然后再除以相同的数字。不过这并不完美:在某些情况下,您可能会导致溢出。坦率地说,我更喜欢在服务器上进行更复杂的财务计算,我有货币、二进制编码的十进制或类似的数字类型。

      【讨论】:

        【解决方案4】:

        假设您有一个像“1.6”这样的数字。如果将其格式化为右侧有 6 个零,您将得到“1.600000”。对计算机来说,它仍然是与 1.6 相同的数字,但对您和您的网站来说,如果您的所有数字的长度不同(例如,这可能会损害解析器),它就不一样了。

        因此,为了避免这种情况,toPrecision 返回一个字符串,否则解释器将重新格式化该数字以再次变为 '1.6'。

        【讨论】:

          【解决方案5】:

          您需要一个用于尾随零的字符串。货币显示就是一个很好的例子。

          【讨论】:

            【解决方案6】:

            因为它是一个格式化函数。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-05-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-03-12
              • 2013-10-22
              • 2021-10-09
              相关资源
              最近更新 更多