Javascript parseFloat '1.23e-7' дает 1.23e-7, когда нужно 0.000000123 - PullRequest
9 голосов
/ 08 ноября 2010
parseFloat(1.51e-6);
// returns 0.00000151

parseFloat(1.23e-7);
// returns 1.23e-7
// required 0.000000123

Я сортирую столбцы таблицы, содержащие широкий диапазон чисел с плавающей запятой, некоторые представлены в научной нотации.

Я использую плагин jQuery tablesorter2.0, который использует parseFloat для ячеек, начинающихся с цифры. Проблема в том, что parseFloat возвращает очень маленькие числа, представленные как 1.23e-7 в виде строки, и не расширяет это значение до 0.000000123. В результате таблица сортировщика сортирует содержимое столбца в виде текста вместо чисел.

**Column To Sort**
2.34
1.01
13.56
1.23e-7

**After Sort Now**
1.01
1.23e-7
13.56
2.34

**Expect**
1.23e-7
1.01
2.34
13.56

Существует ли эффективный способ представления очень маленьких чисел научных обозначений в виде расширенных чисел с плавающей запятой?

Решение:

TableSorter определяет, как сортировать столбец на основе первого автоматического анализатора таблиц, чтобы возвращать true для содержимого ячейки в этом столбце. Если ячейка содержала 1,23e-7, то по умолчанию она сортировалась по тексту, поскольку анализатор «цифр» не интерпретирует это как число.

Итак, чтобы обойти это, следующий код представляет номер научной нотации в виде строки, которую табличный сортировщик может интерпретировать / анализировать как цифру, что обеспечивает числовую сортировку столбца. @bitplitter - спасибо за подсказку toFixed ().

var s = "1.23e-7";
// Handle exponential numbers.
if (s.match(/^[-+]?[1-9]\.[0-9]+e[-]?[1-9][0-9]*$/)) {
  s = (+s).toFixed(getPrecision(s));
}
//returns 0.000000123

// Get a nice decimal place precision for the scientific notation number.
// e.g. 1.23e-7 yields 7+2 places after the decimal point
// e.g. 4.5678e-11 yields 11+4 places after the decimal point
function getPrecision(scinum) {
  var arr = new Array();
  // Get the exponent after 'e', make it absolute.  
  arr = scinum.split('e');
  var exponent = Math.abs(arr[1]);

  // Add to it the number of digits between the '.' and the 'e'
  // to give our required precision.
  var precision = new Number(exponent);
  arr = arr[0].split('.');
  precision += arr[1].length;

  return precision;
}

Ответы [ 3 ]

7 голосов
/ 08 ноября 2010

Вы можете использовать toFixed() вместо parseFloat() для форматирования чисел так, как вы хотите. Например (1.23e-7).toFixed(9) будет отображаться как 0.000000123

Чтобы иметь возможность сортировать их с помощью сравнения строк по умолчанию для сортировки, убедитесь, что все они имеют префиксы с нулями и имеют одинаковый размер, чтобы десятичные точки выстраивались в линию.

Вы можете расширить строковый объект с помощью padLeft следующим образом:

String.prototype.padLeft = function(len, char){
var prefix = '';
var length=this.length;
if(len>length)
 for(var i=0;i < len-length;i++) prefix += char;
return prefix + this;
}

Теперь вы можете звонить ((1.23e-7).toFixed(9)).padLeft(15,'0')

7 голосов
/ 04 апреля 2011

Несмотря на то, что ОП опубликовал свое решение, я хотел бы поделиться довольно простым решением, на которое я наткнулся, которое основано на синтаксических анализаторах исходного кода и регулярном выражении, заданном JasonS для другой вопрос .

// add parser through the tablesorter addParser method 
$.tablesorter.addParser({ 
// set a unique id
id: 'scinot', 
is: function(s) { 
    return /[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?/.test(s); 
}, 
format: function(s) { 
    return $.tablesorter.formatFloat(s);
}, 
type: 'numeric' 
});

Он работает на моих таблицах с почти всеми значениями, приведенными в научной записи. Он автоматически определяет (часть is:) и правильно сортирует несколько полей. Надеюсь, это поможет другим, кто может наткнуться на этот вопрос.

3 голосов
/ 08 ноября 2010

проблема не в parseFloat, а в сортировке, которая использует сравнение строк по умолчанию.Попробуйте принудительное сравнение чисел:

a.sort(function(x, y) { return x - y })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...