如何在javascript中格式化浮点?

如何在javascript中格式化浮点?,javascript,floating-point,Javascript,Floating Point,在JavaScript中,当从浮点转换为字符串时,如何仅获得小数点后的2位数字?例如,0.34而不是0.3445434 var result = Math.round(original*100)/100; ,以防代码不是自解释的 编辑:…或按照建议使用。忘了那个,谢谢(还有一个向上投票)提醒:)有一些函数可以对数字进行四舍五入。例如: var x = 5.0364342423; print(x.toFixed(2)); var x=(23-7.37) x 15.629999999999999

在JavaScript中,当从浮点转换为字符串时,如何仅获得小数点后的2位数字?例如,0.34而不是0.3445434

var result = Math.round(original*100)/100;
,以防代码不是自解释的


编辑:…或按照建议使用
。忘了那个,谢谢(还有一个向上投票)提醒:)

有一些函数可以对数字进行四舍五入。例如:

var x = 5.0364342423;
print(x.toFixed(2));
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
将打印5.04

编辑:

使用
toFixed()时要小心:

首先,使用数字的二进制表示形式对数字进行舍入,这可能会导致意外行为。比如说

(0.595).toFixed(2) === '0.59'
而不是
'0.6'

其次,
toFixed()
存在IE漏洞。在IE中(至少在版本7之前,没有检查IE8),以下情况适用:

(0.9).toFixed(0) === '0'
遵循kkyy的建议或使用自定义的
toFixed()
函数可能是个好主意,例如

function toFixed(value, precision) {
    var power = Math.pow(10, precision || 0);
    return String(Math.round(value * power) / power);
}

也许您还需要十进制分隔符?这是我刚刚做的一个函数:

function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
    if (num < 0)
    {
        num = -num;
        sinal = -1;
    } else
        sinal = 1;
    var resposta = "";
    var part = "";
    if (num != Math.floor(num)) // decimal values present
    {
        part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
        while (part.length < casasDec)
            part = '0'+part;
        if (casasDec > 0)
        {
            resposta = sepDecimal+part;
            num = Math.floor(num);
        } else
            num = Math.round(num);
    } // end of decimal part
    while (num > 0) // integer part
    {
        part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
        num = Math.floor(num/1000);
        if (num > 0)
            while (part.length < 3) // 123.023.123  if sepMilhar = '.'
                part = '0'+part; // 023
        resposta = part+resposta;
        if (num > 0)
            resposta = sepMilhar+resposta;
    }
    if (sinal < 0)
        resposta = '-'+resposta;
    return resposta;
}
函数formatFloat(num、casasDec、sepdecmal、sepMilhar){
if(num<0)
{
num=-num;
正弦=-1;
}否则
正弦=1;
var resposta=“”;
var part=“”;
如果(num!=Math.floor(num))//存在十进制值
{
part=Math.round((num Math.floor(num))*Math.pow(10,casasDec)).toString();//将小数部分转换为整数(舍入)
while(零件长度0)
{
resposta=小数+部分;
num=数学地板(num);
}否则
num=Math.round(num);
}//小数点后
while(num>0)//整数部分
{
part=(num-Math.floor(num/1000)*1000.toString();//part=三个低有效位
num=数学楼层(num/1000);
如果(数值>0)
而(part.length<3)//123.023.123,如果sepMilhar='。'
部分='0'+部分;//023
resposta=零件+resposta;
如果(数值>0)
resposta=sepMilhar+resposta;
}
if(正弦<0)
resposta='-'+resposta;
返回响应;
}

所有这些使用乘数的解决方案都存在问题。不幸的是,kkyy和Christoph的解决方案都是错误的

请用小数点后两位测试代码的数字551.175——它将四舍五入到551.17,而它应该是551.18!但是如果你测试ex.451.175就可以了-451.18。所以很难一眼就发现这个错误

问题在于乘法:尝试551.175*100=55117.499999999(ups!)

所以我的想法是在使用Math.round()之前先用toFixed()处理它


需要注意的另一个问题是,
toFixed()
会在数字末尾产生不必要的零。 例如:

var x = 5.0364342423;
print(x.toFixed(2));
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
其思想是使用
RegExp
清理输出:

function humanize(x){
  return x.toFixed(6).replace(/\.?0*$/,'');
}
RegExp
匹配尾随的零(可选小数点),以确保它也适合整数

humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"

无法避免使用乘法或除法将x.xx5作为实际值的价格四舍五入不一致。如果您需要在客户端计算正确的价格,您应该将所有金额保持为美分。这是由于JavaScript中数值的内部表示的性质造成的。请注意,Excel也有同样的问题,因此大多数人不会注意到这种现象所导致的小错误。然而,无论何时累积大量计算值,误差都可能累积,围绕这一点,有一个完整的理论涉及计算顺序和其他方法,以最大限度地减少最终结果中的误差。为了强调十进制值的问题,请注意0.1+0.2在JavaScript中并不完全等于0.3,而1+2等于3。

/**不要花5分钟,使用我的代码**/
/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) { 
    if (!nbDec) nbDec = 100;
    var a = Math.abs(x);
    var e = Math.floor(a);
    var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
    var signStr = (x<0) ? "-" : " ";
    var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
    var eStr = e.toString();
    return signStr+eStr+"."+decStr;
}

prettyFloat(0);      //  "0.00"
prettyFloat(-1);     // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5);    //  "0.50"
函数prettyFloat(x,nbDec){ 如果(!nbDec)nbDec=100; var a=数学绝对值(x); var e=数学楼层(a); var d=Math.round((a-e)*nbDec);if(d==nbDec){d=0;e++;}
var signStr=(x我使用这段代码来格式化浮点。它基于
toPrecision()
但它去除了不必要的零。我欢迎关于如何简化正则表达式的建议

function round(x, n) {
    var exp = Math.pow(10, n);
    return Math.floor(x*exp + 0.5)/exp;
}
用法示例:

function test(x, n, d) {
    var rounded = rnd(x, d);
    var result = rounded.toPrecision(n);
    result = result.replace(/\.?0*$/, '');
    result = result.replace(/\.?0*e/, 'e');
    result = result.replace('e+', 'e');
    return result;  
}

document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');
功能测试(x,n,d){
var四舍五入=rnd(x,d);
var结果=四舍五入的精度(n);
结果=结果。替换(/\.?0*$/,“”);
结果=结果。替换(/\.?0*e/,'e');
结果=结果。替换('e+','e');
返回结果;
}
编写(测试(1.2000e45,3,2)+'='+'1.2e45'+'
'); 编写(测试(1.2000e+45,3,2)+'='+'1.2e45'+'
'); 编写(测试(1.2340e45,3,2)+'='+'1.23e45'+'
'); 编写(测试(1.2350e45,3,2)+'='+'1.24e45'+'
'); 编写(测试(1.0000,3,2)+'='+'1'+'
'); 编写(测试(1.0100,3,2)+'='+'1.01'+'
'); 编写(测试(1.2340,4,2)+'='+'1.23'+'
'); 编写(测试(1.2350,4,2)+'='+'1.24'+'
');
我想这里的关键是首先要正确地取整,然后才能将其转换为字符串

函数往返(n,p){
常数n1=n*数学功率(10,p+1);
常数n2=数学楼层(n1/10);
如果(n1>=(n2*10+5)){
返回(n2+1)/数学功率(10,p);
}
返回n2/数学功率(10,p);
}
//此线程中列出的所有边缘情况
圆形(95.345,2);/95.35
圆形(95.344,2);//95.34
圆形(5.0364342423,2);/5.04
圆度(0.595,2);/0.60
圆度(0.335,2);/0.34
圆度(0.345,2);/0.35
圆形(551.175,2);/551.18
圆度(0.3445434,2);/0.34
现在可以使用toFixed(p)安全地格式化此值。 因此,就您的具体情况而言:

roundOf(0.3445434,2).toFixed(2);/0.34

如果您希望字符串不带圆,可以使用此正则表达式(可能不是最有效的方法…但非常简单)
function test(x, n, d) {
    var rounded = rnd(x, d);
    var result = rounded.toPrecision(n);
    result = result.replace(/\.?0*$/, '');
    result = result.replace(/\.?0*e/, 'e');
    result = result.replace('e+', 'e');
    return result;  
}

document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');
(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'