Javascript解析浮点数忽略逗号后面的小数

发布于 2024-12-06 22:16:16 字数 334 浏览 1 评论 0原文

这是一个简单的场景。我想显示我的网站上显示的两个值的减法:

//Value on my websites HTML is: "75,00"
var fullcost = parseFloat($("#fullcost").text()); 

//Value on my websites HTML is: "0,03"
var auctioncost = parseFloat($("#auctioncost").text());

alert(fullcost); //Outputs: 75
alert(auctioncost); //Ouputs: 0

谁能告诉我我做错了什么?

Here's a simple scenario. I want to show the subtraction of two values show on my site:

//Value on my websites HTML is: "75,00"
var fullcost = parseFloat($("#fullcost").text()); 

//Value on my websites HTML is: "0,03"
var auctioncost = parseFloat($("#auctioncost").text());

alert(fullcost); //Outputs: 75
alert(auctioncost); //Ouputs: 0

Can anyone tell me what I'm doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

时光病人 2024-12-13 22:16:16

这是“按设计”。 parseFloat 函数只会考虑字符串中的部分,直到达到非 +、-、数字、指数或小数点。一旦它看到逗号,它就会停止查找并只考虑“75”部分。

要解决此问题,请将逗号转换为小数点。

var fullcost = parseFloat($("#fullcost").text().replace(',', '.'));

This is "By Design". The parseFloat function will only consider the parts of the string up until in reaches a non +, -, number, exponent or decimal point. Once it sees the comma it stops looking and only considers the "75" portion.

To fix this convert the commas to decimal points.

var fullcost = parseFloat($("#fullcost").text().replace(',', '.'));
迷爱 2024-12-13 22:16:16

javascript 的 parseFloat 不接受区域设置参数。因此,您必须将 , 替换为 .

parseFloat('0,04'.replace(/,/, '.')); // 0.04

javascript's parseFloat doesn't take a locale parameter. So you will have to replace , with .

parseFloat('0,04'.replace(/,/, '.')); // 0.04
阳光的暖冬 2024-12-13 22:16:16

为什么不使用全球化?这只是当您不使用英语时可能遇到的问题之一:

Globalize.parseFloat('0,04'); // 0.04

stackoverflow 上的一些链接可供查看:

Why not use globalize? This is only one of the issues that you can run in to when you don't use the english language:

Globalize.parseFloat('0,04'); // 0.04

Some links on stackoverflow to look into:

勿忘初心 2024-12-13 22:16:16

parseFloat 根据 JavaScript 进行解析 十进制文字的定义,而不是您所在区域的定义。 (例如,parseFloat 不支持区域设置。)JavaScript 中的十进制文字使用 . 作为小数点。

parseFloat parses according to the JavaScript definition of a decimal literal, not your locale's definition. (E.g., parseFloat is not locale-aware.) Decimal literals in JavaScript use . for the decimal point.

新雨望断虹 2024-12-13 22:16:16

正如 @JaredPar 在他的答案中指出的那样,使用parseFloat 替换

var fullcost = parseFloat($("#fullcost").text().replace(',', '.'));

只需替换逗号与一个dot 会修复,除非它是一个超过数千的数字,例如 1.000.000,00 这样会给你错误的数字。因此,您需要替换逗号并删除

// Remove all dot's. Replace the comma.
var fullcost = parseFloat($("#fullcost").text().replace(/\./g,'').replace(',', '.'));

通过使用两次替换,您将能够处理数据而不会在输出中接收到错误的数字。

As @JaredPar pointed out in his answer use parseFloat with replace

var fullcost = parseFloat($("#fullcost").text().replace(',', '.'));

Just replacing the comma with a dot will fix, Unless it's a number over the thousands like 1.000.000,00 this way will give you the wrong digit. So you need to replace the comma remove the dots.

// Remove all dot's. Replace the comma.
var fullcost = parseFloat($("#fullcost").text().replace(/\./g,'').replace(',', '.'));

By using two replaces you'll be able to deal with the data without receiving wrong digits in the output.

眼泪都笑了 2024-12-13 22:16:16

对于到达这里的任何人,想知道如何处理可能涉及逗号(,)和句号(.)但确切的数字格式可能不知道的问题 - 这这就是我在使用 parseFloat() 之前更正字符串的方法(借鉴其他答案的想法):

function preformatFloat(float){
   if(!float){
      return '';
   };

   //Index of first comma
   const posC = float.indexOf(',');

   if(posC === -1){
      //No commas found, treat as float
      return float;
   };

   //Index of first full stop
   const posFS = float.indexOf('.');

   if(posFS === -1){
      //Uses commas and not full stops - swap them (e.g. 1,23 --> 1.23)
      return float.replace(/\,/g, '.');
   };

   //Uses both commas and full stops - ensure correct order and remove 1000s separators
   return ((posC < posFS) ? (float.replace(/\,/g,'')) : (float.replace(/\./g,'').replace(',', '.')));
};
// <-- parseFloat(preformatFloat('5.200,75'))
// --> 5200.75

至少,这将允许解析英国/美国和欧洲十进制格式(假设字符串包含有效的数字)。

For anyone arriving here wondering how to deal with this problem where commas (,) and full stops (.) might be involved but the exact number format may not be known - this is how I correct a string before using parseFloat() (borrowing ideas from other answers):

function preformatFloat(float){
   if(!float){
      return '';
   };

   //Index of first comma
   const posC = float.indexOf(',');

   if(posC === -1){
      //No commas found, treat as float
      return float;
   };

   //Index of first full stop
   const posFS = float.indexOf('.');

   if(posFS === -1){
      //Uses commas and not full stops - swap them (e.g. 1,23 --> 1.23)
      return float.replace(/\,/g, '.');
   };

   //Uses both commas and full stops - ensure correct order and remove 1000s separators
   return ((posC < posFS) ? (float.replace(/\,/g,'')) : (float.replace(/\./g,'').replace(',', '.')));
};
// <-- parseFloat(preformatFloat('5.200,75'))
// --> 5200.75

At the very least, this would allow parsing of British/American and European decimal formats (assuming the string contains a valid number).

囚你心 2024-12-13 22:16:16

最好使用这种语法来替换一百万个情况下的所有逗号 1,234,567

var string = "1,234,567";
string = string.replace(/[^\d\.\-]/g, ""); 
var number = parseFloat(string);
console.log(number)

g 表示删除所有逗号。

此处查看 Jsfiddle 演示

It is better to use this syntax to replace all the commas in a case of a million 1,234,567

var string = "1,234,567";
string = string.replace(/[^\d\.\-]/g, ""); 
var number = parseFloat(string);
console.log(number)

The g means to remove all commas.

Check the Jsfiddle demo here.

虫児飞 2024-12-13 22:16:16

JS 中的数字使用 .(句号/句点)字符来指示小数点,而不是 ,(逗号)。

Numbers in JS use a . (full stop / period) character to indicate the decimal point not a , (comma).

紅太極 2024-12-13 22:16:16

你做错的地方是向 parseFloat() 提供以面向人类的表示法表示小数的字符串,而 parseFloat() 仅接受与 JavaScript 数字文字与区域无关,始终使用点作为小数分隔符,并且没有千位分隔符。

此外,在所有答案中使用的这个 parseFloat() 函数在接受正确输入时过于慷慨,从而阻止了对大多数情况下不正确输入的检测:

Input      Result
'1Hello'   1
'1 and 2'  1
'1.2+3.4'  1.2
' 25  '    25

为了获得更严格的 输入为了更好地控制行为,我建议您实现自己的解析函数。这是我的:

// Parse a decimal fraction with specified thousands
// and group separators:
function /* number */ parse_float
(   /* string */ s      , // string to parse
    /* string */ thousep, // thousands separator, empty string if none
    /* string */ decsep   // decimal separator  , empty string if none
)
{   var /* integer */ whole, frac ; // whole and fractinal parts
    var /* integer */ wnext, fnext; // position of next char after parse
    var /* integer */ fraclen     ; // length of fractional part
    var /* integer */ ofs         ; // offset of the first digit
    var /* boolean */ done        ; // entire string scanned?
    var /* integer */ sign        ; // sign of result
    var /* number  */ res         ; // result
        /* labels  */ end: { whole: {

    // Check parameter types and availability:
    req_param( 's'      , s      , 'string' );
    req_param( 'thousep', thousep, 'string' );
    req_param( 'decsep' , decsep , 'string' );
    
    frac    = 0;
    fraclen = 0;
    res     = NaN;
    // Account for a possible sign:
    switch( s.charAt(0) )
    {   case '-': sign = -1; ofs = 1; break;
        case '+': sign = +1; ofs = 1; break;
        default : sign = +1; ofs = 0; break;
    }

    [done, wnext, whole] = parse_int_ts( s, ofs, thousep );
    if( isNaN( whole )               )           break end;
    if( done                         )           break whole;
    if( s.charAt( wnext ) !== decsep )           break end; 
    
    [done, fnext, frac] = parse_int( s, 0, wnext + 1 );
    if( !done                        )           break end;

    fraclen = fnext - wnext - 1;
    if( fraclen === 0                )           break end;

    } /* whole: */ res = ( whole + frac / Math.pow( 10, fraclen ) ) * sign;
    } /* end:   */ return res;
}

// Require that a value be specified and have the expected type:
function req_param( /* string */ param, /* variant */ val, /* string */ type )
{   var /* string */ errmsg;

    errmsg = ''; if( val === undefined   ) errmsg = 'is undefined';
    else         if( val === null        ) errmsg = 'is null';
    else         if( typeof val !== type ) errmsg = `must of type \`${type}'`;

    if( errmsg !== '' ) // there has been an error
    {   throw new Error(`Parameter \`${param}' ${errmsg}.`);  }
}

// Parse an integer with a specified thousands separator:
function /* object[] */ parse_int_ts
(   /* string    */ s    , // input string
    /* integer   */ start, // start position
    /* character */ sep  , // thousands separator
)
// Returns an array of:
//   0: boolean -- entire string was scanned
//   1: integer -- index of next character to scan
//   2: integer -- resulting inteer 
{   var /* boolean */ full;
    var /* integer */ next;
    var /* integer */ res;
    var /* integer */ len;
    var /* integer */ psep;
    var /* integer */ result;
    
    res     = 0;
    psep    = 0;
    while( true )
    {   result = NaN; // mark an error
        [full, next, res] = parse_int( s, res, start );
        len = next - start;
        if( len === 0  )                 break; // nothing parsed
        if( sep !== '' )
        {   if( psep  >  0 && len !== 3 ) break; // non-first group not 3 digits
            if( psep === 0 && len  >  3 ) break; // first group longer than 3 digits
        }
        result = res; // mark success
        if( s.charAt(next) !== sep )     break;
        if(  full   )                    break;
        start = next;
        psep  = next;
        start = start + 1;
    }
    return [full, next, result];
}

// Parse a compact of digits beginning at position `start' 
// in string `s' as an integer number:
function /* object[]*/ parse_int
(   /* string  */ s   , // input string
    /* integer */ init, // initial value
    /* integer */ start // start position in `s'
)
// Returns an array of:
// 0: boolean -- entire string was scanned
// 1: integer -- index of next character to scan
// 2: integer -- result
{   const /* integer */ ASCII_0 = 48;

    var /* boolean   */ full; // \
    var /* integer   */ next; //  > the return value
    var /* integer   */ res ; // /
    var /* integer   */ n, i; // string length and current position
    var /* integer   */ code; // character code

    n    = s.length;
    full = true;
    next = n;
    res  = init;
    for( i = start; i < n; i += 1 )
    {   code = s.charCodeAt(i);
        if( code < ASCII_0 || code >= ASCII_0 + 10 )
        {   next = i;
            full = false;
            break;
        }
        res = res * 10 + code - ASCII_0;
    }
    if( code === undefined ) res = NaN;
    return [ full, next, res ];
}

还有一个使用 parse_float() 来解析您的格式的数字的测试程序:

function test( /* string */ s )
{   var res;
    res = parse_float( s, ' ', ',' );
    console.log(`${('            ' + `[${s}]`).slice(-12)} => ${res}`);
}

test( ''           );
test( '12'         );
test( '12a'        );
test( '12,'        );
test( '12,345'     );
test( '12 345'     );
test( '123 45'     );
test( '1 234 567'  );
test( '12 345 56'  );
test( '12345'      );
test( '12 435,678' );
test( '+1,2'       );
test( '-2 345'     );

它写道:

          [] => NaN
        [12] => 12
       [12a] => NaN
       [12,] => NaN
    [12,345] => 12.345
    [12 345] => 12345
    [123 45] => NaN
 [1 234 567] => 1234567
 [12 345 56] => NaN
     [12345] => NaN
[12 435,678] => 12435.678
      [+1,2] => 1.2
    [-2 345] => -2345

What you do wrong is feed parseFloat() with strings that represent decimal fractions in a human-oriented notation, whereas parseFloat() accepts only the standard format corresponding with the JavaScript number literals, which are region-independent, always use the dot as the decimal separator, and have no thousands separator.

Futhermore, this parseFloat() function, used in all the answers, is too generous in what it accepts as correct input, preventing the detection of what in most cases is incorrect input:

Input      Result
'1Hello'   1
'1 and 2'  1
'1.2+3.4'  1.2
' 25  '    25

In order to get a stricter and therefore better-controlled behavior, I recommend that you implement your own parsing function. Here is mine:

// Parse a decimal fraction with specified thousands
// and group separators:
function /* number */ parse_float
(   /* string */ s      , // string to parse
    /* string */ thousep, // thousands separator, empty string if none
    /* string */ decsep   // decimal separator  , empty string if none
)
{   var /* integer */ whole, frac ; // whole and fractinal parts
    var /* integer */ wnext, fnext; // position of next char after parse
    var /* integer */ fraclen     ; // length of fractional part
    var /* integer */ ofs         ; // offset of the first digit
    var /* boolean */ done        ; // entire string scanned?
    var /* integer */ sign        ; // sign of result
    var /* number  */ res         ; // result
        /* labels  */ end: { whole: {

    // Check parameter types and availability:
    req_param( 's'      , s      , 'string' );
    req_param( 'thousep', thousep, 'string' );
    req_param( 'decsep' , decsep , 'string' );
    
    frac    = 0;
    fraclen = 0;
    res     = NaN;
    // Account for a possible sign:
    switch( s.charAt(0) )
    {   case '-': sign = -1; ofs = 1; break;
        case '+': sign = +1; ofs = 1; break;
        default : sign = +1; ofs = 0; break;
    }

    [done, wnext, whole] = parse_int_ts( s, ofs, thousep );
    if( isNaN( whole )               )           break end;
    if( done                         )           break whole;
    if( s.charAt( wnext ) !== decsep )           break end; 
    
    [done, fnext, frac] = parse_int( s, 0, wnext + 1 );
    if( !done                        )           break end;

    fraclen = fnext - wnext - 1;
    if( fraclen === 0                )           break end;

    } /* whole: */ res = ( whole + frac / Math.pow( 10, fraclen ) ) * sign;
    } /* end:   */ return res;
}

// Require that a value be specified and have the expected type:
function req_param( /* string */ param, /* variant */ val, /* string */ type )
{   var /* string */ errmsg;

    errmsg = ''; if( val === undefined   ) errmsg = 'is undefined';
    else         if( val === null        ) errmsg = 'is null';
    else         if( typeof val !== type ) errmsg = `must of type \`${type}'`;

    if( errmsg !== '' ) // there has been an error
    {   throw new Error(`Parameter \`${param}' ${errmsg}.`);  }
}

// Parse an integer with a specified thousands separator:
function /* object[] */ parse_int_ts
(   /* string    */ s    , // input string
    /* integer   */ start, // start position
    /* character */ sep  , // thousands separator
)
// Returns an array of:
//   0: boolean -- entire string was scanned
//   1: integer -- index of next character to scan
//   2: integer -- resulting inteer 
{   var /* boolean */ full;
    var /* integer */ next;
    var /* integer */ res;
    var /* integer */ len;
    var /* integer */ psep;
    var /* integer */ result;
    
    res     = 0;
    psep    = 0;
    while( true )
    {   result = NaN; // mark an error
        [full, next, res] = parse_int( s, res, start );
        len = next - start;
        if( len === 0  )                 break; // nothing parsed
        if( sep !== '' )
        {   if( psep  >  0 && len !== 3 ) break; // non-first group not 3 digits
            if( psep === 0 && len  >  3 ) break; // first group longer than 3 digits
        }
        result = res; // mark success
        if( s.charAt(next) !== sep )     break;
        if(  full   )                    break;
        start = next;
        psep  = next;
        start = start + 1;
    }
    return [full, next, result];
}

// Parse a compact of digits beginning at position `start' 
// in string `s' as an integer number:
function /* object[]*/ parse_int
(   /* string  */ s   , // input string
    /* integer */ init, // initial value
    /* integer */ start // start position in `s'
)
// Returns an array of:
// 0: boolean -- entire string was scanned
// 1: integer -- index of next character to scan
// 2: integer -- result
{   const /* integer */ ASCII_0 = 48;

    var /* boolean   */ full; // \
    var /* integer   */ next; //  > the return value
    var /* integer   */ res ; // /
    var /* integer   */ n, i; // string length and current position
    var /* integer   */ code; // character code

    n    = s.length;
    full = true;
    next = n;
    res  = init;
    for( i = start; i < n; i += 1 )
    {   code = s.charCodeAt(i);
        if( code < ASCII_0 || code >= ASCII_0 + 10 )
        {   next = i;
            full = false;
            break;
        }
        res = res * 10 + code - ASCII_0;
    }
    if( code === undefined ) res = NaN;
    return [ full, next, res ];
}

And a test program that uses parse_float() to parse numbers of your format:

function test( /* string */ s )
{   var res;
    res = parse_float( s, ' ', ',' );
    console.log(`${('            ' + `[${s}]`).slice(-12)} => ${res}`);
}

test( ''           );
test( '12'         );
test( '12a'        );
test( '12,'        );
test( '12,345'     );
test( '12 345'     );
test( '123 45'     );
test( '1 234 567'  );
test( '12 345 56'  );
test( '12345'      );
test( '12 435,678' );
test( '+1,2'       );
test( '-2 345'     );

It writes:

          [] => NaN
        [12] => 12
       [12a] => NaN
       [12,] => NaN
    [12,345] => 12.345
    [12 345] => 12345
    [123 45] => NaN
 [1 234 567] => 1234567
 [12 345 56] => NaN
     [12345] => NaN
[12 435,678] => 12435.678
      [+1,2] => 1.2
    [-2 345] => -2345
凉墨 2024-12-13 22:16:16

就我而言,我已经有一个句号(.)和一个逗号(,),所以对我有用的是替换逗号(,) 和一个空字符串,如下所示:

parseFloat('3,000.78'.replace(',', '')) 

假设现有数据库中的金额为 3,000.78。结果是:3000.78,没有起始逗号(,)

In my case, I already had a period(.) and also a comma(,), so what worked for me was to replace the comma(,) with an empty string like below:

parseFloat('3,000.78'.replace(',', '')) 

This is assuming that the amount from the existing database is 3,000.78. The results are: 3000.78 without the initial comma(,).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文