숫자에서 중요하지 않은 후행 0을 제거 하시겠습니까?


157

숫자에서 후미의 0을 제거하는 표준 API 호출을 놓쳤습니까?

전의.

var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001

Number.toFixed () 및 Number.toPrecision ()은 내가 찾고있는 것이 아닙니다.


6
1.234000 === 1.234.
Gumbo

5
당신이 경고 (X)를 할 경우 네, 그것은 후행 0없이 팝업
JKirchartz

50
여러 클라이언트와 작업 한 후에는 1.234000 === 1.234이지만 클라이언트가 필요하지 않은 경우 0을 더보고 싶지 않다는 것을 간증 할 수 있습니다.
contactmatt

16
사용 parseFloat(n)?
Mr. Alien

이것은 모든 경우를 다루는 가장 쉬운 솔루션이었습니다. @ Mr.Alien 감사합니다.
James Perih

답변:


140

문자열로 변환하면 문자열이 아닌 숫자로 작성된 이후 변수에 저장되지 않는 후행 0이 표시되지 않습니다.

var n = 1.245000
var noZeroes = n.toString() // "1.245" 

6
0을 제거하는 코드를 게시하려고했지만 Daniel의 솔루션이 작동하는 것 같습니다. "1.2345000"과 같은 문자열에서도 작동합니다. ( "1.2345000"* 1) .toString (); // 1.2345가 됨
Steven

7
물론 var가 이미 문자열이라면 먼저 숫자로 변환 한 다음 다시 되돌려 야합니다.
derekcohen

이것은 훌륭하게 작동했습니다. 나는 같은 문제가 있었고 float를 문자열로 변환 한 다음 parseFloat를 사용하여 후행 0없이 올바른 형식으로 다시 가져 왔습니다.
Matt West

10
이것은 완전한 해결책이 아닙니다. 부동 소수점 표현 오류가있는 변수가있을 때 작동하지 않습니다 : var n = 1.245000000000001(사용자에게 표현하기에 무의미하다고 가정)
augur

7
1231111111111111111111111111111111222222222222222222222222222222222222222222222222.00와 같은 숫자에 대해 예기치 않은 결과가 발생할 수 있습니다. 문자열 표현은 지수 형식입니다 : 1.231111111111111e + 81
Stas Makutin

227

필자는 .toFixed()필요한 곳 에서 사용 하고 싶었던 비슷한 인스턴스를 가지고 있었지만 그렇지 않을 때 패딩을 원하지 않았습니다. 그래서 toFixed와 함께 parseFloat를 사용했습니다.

패딩없이 고정

parseFloat(n.toFixed(4));

거의 같은 일을하는 다른 옵션
이 답변은 결정에 도움이 될 수 있습니다

Number(n.toFixed(4));

toFixed숫자를 특정 길이로 반올림 / 채울뿐만 아니라 문자열로 변환합니다. 다시 숫자 형식으로 변환하면 숫자를 산술적으로 사용하는 것이 더 안전 할뿐만 아니라 후행 0도 자동으로 삭제합니다. 예를 들면 다음과 같습니다.

var n = "1.234000";
    n = parseFloat(n);
 // n is 1.234 and in number form

후행 0으로 숫자를 정의하더라도 삭제됩니다.

var n = 1.23000;
 // n == 1.23;

이것은 관련된 소수점 이하 자릿수가 toFixed 인수보다 크거나 같은 경우에만 작동합니다. 숫자가 예를 들어 1.200000이면 toFixed (3)의 결과는 1.200이므로 모든 후행 0이 제거되지 않습니다.
Leopoldo Sanczyk

@LeopoldoSanczyk 아니요, 문자열을 반환하기 때문에 toFixed를 사용하는 경우에만 해당됩니다. 숫자 유형은 자동으로 후행 0을 잃습니다. 그래서 두 가지를 함께 사용했습니다.
게리

@ 게리, 나는 내 의견을 철회, 나는 parseFloat(n).toFixed(4);당신의 실제 답변 대신에 보았다 . 죄송 해요.
Leopoldo Sanczyk

2
왜 안돼 +(n.toFixed(4))?
Константин Ван

3
공감! 단지 당신의 대답 0.00000005 하나의 문제는 내가 최종 필요에 따라 제로 제거 할 수있는 등 0.000058000 작은 숫자 함께 일하고,이 문제없이 하찮은 제로를 제거하는 방법 5E-8로 변환됩니다
PirateApp

29

나는 먼저 matti-lyra와 gary의 답변을 조합하여 사용했습니다.

r=(+n).toFixed(4).replace(/\.0+$/,'')

결과 :

  • 1234870.98762341 : "1234870.9876"
  • 1230009100 : "1230009100"
  • 0.0012234 : "0.0012"
  • 0.1200234 : "0.12"
  • 0.000001231 : "0"
  • 0.10001 : "0.1000"
  • "asdf": "NaN"(런타임 오류가 없음)

다소 문제가되는 경우는 0.10001입니다. 이 더 긴 버전을 사용하게되었습니다.

    r = (+n).toFixed(4);
    if (r.match(/\./)) {
      r = r.replace(/\.?0+$/, '');
    }
  • 1234870.98762341 : "1234870.9876"
  • 1230009100 : "1230009100"
  • 0.0012234 : "0.0012"
  • 0.1200234 : "0.12"
  • 0.000001231 : "0"
  • 0.10001 : "0.1"
  • "asdf": "NaN"(런타임 오류가 없음)

업데이트 : 이것은 Gary의 최신 버전입니다 (의견 참조).

r=(+n).toFixed(4).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1')

위와 동일한 결과를 제공합니다.


1
내가 생각하는 순수한 정규식 솔루션이 있습니다toFixed(4).replace(/([0-9]+(\.[1-9]+)?)(\.?0+$)/,"$1")
Gary

1
가! 분명히 나는 ​​다른 사람들보다 내 자신의 RegEx를 깨는 데 거의 능숙하지 않습니다. 나는 이것이 나를 이길 못하게합니다! 나는 당신의 모든 테스트 케이스와 내가 생각할 수있는 (유효한) 모든 것에 대해 이것을 실행했습니다.([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)
Gary

1
정규 표현식은 욕심이 많으며 때로는 정수 부분에서 "0"을 제거합니다! :-( 왜 안돼 replace(/[,.][1-9]+(0+)/,'')?
Sebastian Sebald

1
과소 평가 된 답변.
찰리

1
@ w00t 아, 죄송합니다, 지금 이해합니다. 나는 내가 만들 때 테스트 한 방식이었습니다 (위 링크 참조). toFixed를 사용할 때 숫자가 점을 보장하기 때문에 실패하지 않지만 정규 표현식이 점이없는 정수를 포함하여 모든 숫자에서 작동하기를 원했기 때문에 테스트에서 실패했습니다. 고정하지 않으면 끝에 0을 먹는다. 내 잘못이야.
geekley

21

toFixed방법은 필요한 경우 적절한 반올림을 수행합니다. 또한 항상 0이 아닌 후행 0을 추가합니다.

(4.55555).toFixed(2);
//-> "4.56"

(4).toFixed(2);
//-> "4.00"

반환 값을 숫자로 캐스팅하면 후행 0이 삭제됩니다. 이것은 자신의 반올림 또는 절단 수학을 수행하는 것보다 간단한 접근법입니다.

+(4.55555).toFixed(2);
//-> 4.56

+(4).toFixed(2);
//-> 4

1
까다 롭지 만 정확히 내가 찾은 것 : 중요한 후행 0을 제거합니다 (물론 우리는 toFixed전화를 통해 중요했습니다 ). 이상한 UX 엣지 케이스입니다.
worc

12

기본적으로 동일한 요구 사항이 있었으며이 기능에 대한 기본 제공 메커니즘이 없음을 발견했습니다.

후행 0을 다듬는 것 외에도 사용자의 현재 로캘 (예 : 123,456.789)에 대한 출력을 반올림하고 형식을 지정해야했습니다.

이것에 대한 나의 모든 작업은 GitHub에서 prettyFloat.js (MIT 라이센스)로 포함되었습니다 : https://github.com/dperish/prettyFloat.js


사용 예 :

prettyFloat(1.111001, 3) // "1.111"
prettyFloat(1.111001, 4) // "1.111"
prettyFloat(1.1111001, 5) // "1.1111"
prettyFloat(1234.5678, 2) // "1234.57"
prettyFloat(1234.5678, 2, true) // "1,234.57" (en-us)


2018 년 8 월 업데이트


모든 최신 브라우저는 이제 언어 구분 문자열 비교, 숫자 형식 및 날짜 및 시간 형식을 제공 하는 ECMAScript Internationalization API를 지원합니다 .

let formatters = {
    default: new Intl.NumberFormat(),
    currency: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
    whole: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
    oneDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 1, maximumFractionDigits: 1 }),
    twoDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 })
};

formatters.twoDecimal.format(1234.5678);  // result: "1,234.57"
formatters.currency.format(28761232.291); // result: "$28,761,232"

구형 브라우저의 경우 다음 polyfill을 사용할 수 있습니다. https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en


이것은 찾고 있던 것입니다. npm 패키지를 작성해야합니다.
EnZo

이제 국제화 API를 통해 가능하므로 이것을 업데이트해야합니다.
duffish

2
공유와 업데이트에 감사합니다.
jaggedsoft

11

이런 식으로 곱하면 어떻습니까?

var x = 1.234000*1; // becomes 1.234

var y = 1.234001*1; // stays as 1.234001

9

이 숫자를 사용하여 부동 숫자를 최소화 할 수 있습니다

var n = 0.0000;
n = parseFloat(n.toString()); 

//output n = 0; 
// n = 3.14000; --> n = 3.14;

7

순수한 정규식 답변

n.replace(/(\.[0-9]*[1-9])0+$|\.0*$/,'$1');

아무도 왜 아무도주지 않았는지 궁금합니다!


숫자로는 작동하지 않습니다 (숫자는 원래 질문에 명시되어 있음). 그래도 문자열 표현에 대한 솔루션을 좋아합니다!
BennyHilarious

6

Django가 Decimal 유형 값을 텍스트 필드에 표시 할 때이 문제도 해결해야했습니다. 예를 들어 '1'이 값일 때 '1.00000000'으로 표시됩니다. '1.23'이 값이면 '1.23000000'을 표시합니다 ( 'decimal_places'설정이 8 인 경우)

parseFloat 를 사용 하는 것은 옵션이 아닙니다. 정확히 동일한 값을 반환하지 않을 수도 있기 때문입니다. toFixed 는 아무것도 반올림하지 않기 때문에 옵션이 아니므로 함수를 만들었습니다.

function removeTrailingZeros(value) {
    value = value.toString();

    # if not containing a dot, we do not need to do anything
    if (value.indexOf('.') === -1) {
        return value;
    }

    # as long as the last character is a 0 or a dot, remove it
    while((value.slice(-1) === '0' || value.slice(-1) === '.') && value.indexOf('.') !== -1) {
        value = value.substr(0, value.length - 1);
    }
    return value;
}

이것은 작동하지만 실행 당 여러 문자열을 생성하기 때문에 상당히 비효율적입니다. 좋은 숫자가 .00000 인 테이블의 모든 셀에서 이것을 실행한다고 상상해보십시오. 더 나은 옵션은 몇 개의 후행 0이 있는지 확인한 다음 슬라이스를 한 번에 수행하는 것입니다. 캐릭터가 무엇인지 결정하는 것은 크게 효율적이며 문자열을 나누는 것이 덜 효과적입니다.
Derek Nigel Bartram

나는 당신의 제안과 비슷한 것을했습니다 Derek : github.com/rek/remove-trailing-zeros/blob/master/…
rekarnar

성능 테스트는 여기 있습니다 : jsperf.com/remove-trailing-zeros/1 , 당신은 옳았습니다. 0을 찾아서 제거하는 것이 훨씬 빠릅니다!
rekarnar

4

이 솔루션 중 어느 것도 매우 적은 수의 나를 위해 효과가 없었습니다. http://numeraljs.com/이 문제를 해결했습니다.

parseFloat(0.00000001.toFixed(8));
// 1e-8

numeral(0.00000001).format('0[.][00000000]');
// "0.00000001"

6 개 이상의 정밀도를 처리 할 수 ​​없습니다. 나는이 라이브러리가 작은 숫자를 의미한다면 쓸모가 없다고 말하고 싶습니다. 확실히 권장하지 않습니다.
Daniel Kmak

2

어떤 이유로 든 Floats를 사용할 수없고 (관련된 Floats와 같은) 이미 올바른 숫자를 나타내는 문자열에서 시작하는 경우이 솔루션이 유용 할 수 있습니다. 숫자를 나타내는 문자열을 후행 0이없는 숫자를 나타내는 문자열로 변환합니다.

function removeTrailingZeroes( strAmount ) {
    // remove all trailing zeroes in the decimal part
    var strDecSepCd = '.'; // decimal separator
    var iDSPosition = strAmount.indexOf( strDecSepCd ); // decimal separator positions
    if ( iDSPosition !== -1 ) {
        var strDecPart = strAmount.substr( iDSPosition ); // including the decimal separator

        var i = strDecPart.length - 1;
        for ( ; i >= 0 ; i-- ) {
            if ( strDecPart.charAt(i) !== '0') {
                break;
            }
        }

        if ( i=== 0 ) {
            return strAmount.substring(0, iDSPosition);
        } else {
            // return INTPART and DS + DECPART including the rightmost significant number
            return strAmount.substring(0, iDSPosition) + strDecPart.substring(0,i + 1);
        }
    }

    return strAmount;
}

0

모든 답변과 의견을 읽은 후 나는 이것으로 끝났습니다.

function isFloat(n) {
    let number = (Number(n) === n && n % 1 !== 0) ? eval(parseFloat(n)) : n;
    return number;
}

나는 eval어떻게 든 사용하는 것이 해로울 수 있다는 것을 알고 있지만 이것은 많은 도움이되었습니다.

그래서:

isFloat(1.234000);     // = 1.234;
isFloat(1.234001);     // = 1.234001
isFloat(1.2340010000); // = 1.234001

소수점 이하 자릿수를 제한하려면 toFixed()다른 사람이 지적한대로 사용하십시오 .

let number = (Number(n) === n && n % 1 !== 0) ? eval(parseFloat(n).toFixed(3)) : n;

그게 다야.


0

후행 0을 제거해야하지만 0을 포함하여 최소 2 개의 소수점을 유지 하십시오.
작업중 인 숫자는 .toFixed (6)에 의해 생성 된 6 개의 십진수 문자열입니다.

예상 결과:

var numstra = 12345.000010 // should return 12345.00001
var numstrb = 12345.100000 // should return 12345.10
var numstrc = 12345.000000 // should return 12345.00
var numstrd = 12345.123000 // should return 12345.123

해결책:

var numstr = 12345.100000

while (numstr[numstr.length-1] === "0") {           
    numstr = numstr.slice(0, -1)
    if (numstr[numstr.length-1] !== "0") {break;}
    if (numstr[numstr.length-3] === ".") {break;}
}

console.log(numstr) // 12345.10

논리:

문자열 마지막 문자가 0 인 경우 루프 기능을 실행하십시오.
마지막 문자를 제거하고 문자열 변수를 업데이트하십시오.
업데이트 된 문자열 마지막 문자가 0이 아닌 경우 루프를 종료하십시오.
마지막 세 번째 문자로 업데이트 된 문자열이 부동 소수점 인 경우 루프를 종료하십시오.


-1

가능한 해결책은 다음과 같습니다.

var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001

eval(x) --> 1.234
eval(y) --> 1.234001

4
이 간단한 작업을 위해 eval이 필요하지 않습니다! parseFloat()훨씬 적합합니다.
hutchbat

6
평가 == 악. 이제까지 그것을 사용하지 마십시오
eagor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.