JavaScript的parseFloat函数对'1.23e-7'的解析会得到1.23e-7而非所需的0.000000123。

10
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。 因此,tablesorter按文本而不是数字排序列的内容。
**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 根据 tablesorter 自动解析器中第一个返回 true 的值来确定如何对列进行排序。如果单元格包含 1.23e-7,则默认按文本排序,因为“digit”解析器不将其解释为数字。
为了解决这个问题,以下代码将科学计数法数字表示为一个字符串,tablesorter 可以将其解释/解析为数字,并确保对该列进行数字排序。 感谢 @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个回答

10
你可以使用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')

toFixed() 方法返回一个字符串,仍需要将其转换为数字以进行数值排序。 - shanesolo
我编辑了我的答案,以说明您如何将数字作为字符串进行排序。 - Bitsplitter

7

虽然OP已经发布了他的解决方案,但我想分享一个更简单的解决方案,它基于tablesorter中的解析器源代码和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
问题不在于parseFloat,而是默认使用字符串比较的排序。尝试强制使用数字比较:
a.sort(function(x, y) { return x - y })

但是表格排序器必须从<td>内容开始,这些内容当然是字符串。 - Pointy
将 parseFloat() 应用于 <td> 字符串内容会返回一个数字,可以供 sort 函数使用... 将研究在 tablesorter 中实现此功能的自定义解析器... 在取得任何进展时会进行更新... 感谢大家! - shanesolo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接