숫자에서 중요하지 않은 후행 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.