2009-02-02 8 views
2

Посмотреть этот код:Почему toPrecision возвращает строку?

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

я ожидал бы номер. Если «isNotNumber» должно быть действительным числом, переделка решение:

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

[Редактировать] спасибо за ваши ответы. Точность не столь точна, как я заключаю. Он может представлять общее количество цифр номера или количество дробных цифр. Большинство людей в Нидерландах (откуда я родом) думают о точности в «количестве дробных цифр». Метод javascript toPrecision относится к первому представлению, поэтому это запутывает. В любом случае, этот метод позволяет ввести «ложную точность», правильно? Для второго значения мы имеем toFixed, то же самое для этого (возвращает строку, возможность ложной точности).

Во всяком случае, сделав переосмысление колеса своим главным увлечением, я играл вокруг, чтобы построить объект float 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 

ответ

10

Из документов: «Возвращает строку, представляющую объект Number, с указанной точностью».

toPrecision() Предназначен для форматирования вывода, и в этом случае строка является наиболее разумным результатом. Он представляет конечный результат в форме, которая не будет искажена дальнейшими манипуляциями.

Если вы хотите сделать некоторую усеченность точности по причинам расчета, я стараюсь умножить на 10^n, где n - это цифры, которые я хочу сохранить, извлечь из них целое число и затем снова разделить на то же самое. Это не идеально, хотя: в некоторых ситуациях вы можете предложить переполнение. Честно говоря, я предпочитаю делать более сложные финансовые расчеты на сервере, где у меня есть валюта, двоично-кодированные десятичные или похожие числовые типы.

3

Поскольку это функция форматирования.

1

Вам нужна строка для конечных нулей. Хорошим примером является отображение валюты.

10

Предположим, у вас есть номер типа «1.6». Если вы отформатируете его, чтобы иметь 6 нулей вправо, вы получите «1.600000». Для компьютера это все равно то же число, что и 1,6, но для вас и вашего сайта это не то же самое, если все ваши номера имеют разные длины (что может повредить парсер, например).

Так, чтобы избежать этого, toPrecision возвращает строку, иначе интерпретатор переформатировал бы номер, чтобы снова стать «1.6».

-1

Проблема заключается в использовании toPrecision. Попробуйте это.

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

Я совершенно не понимаю, что вы имеете в виду! – KooiInc

5

Цель состоит в toPrecision усечение значительные десятичных цифр в Number на заданную величину. Но тип данных внутренних представлений Number s равен двоичный код IEEE-754 double.Поэтому невозможно для хранения точный возвращаемое значение в Number большую часть времени. В результате этой неточности возвращаемое значение будет иметь бесконечное количество десятичных цифр, которое приведет к нулю toPrecision.

Таким образом, единственным разумным решением этой проблемы является возвращение десятичных цифр. И в настоящее время единственным разумным типом JS для десятичных цифр является String.


Вот пример для уточнения неточностей в Number с, если используется для десятичных цифр:

// 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 
Смежные вопросы