programing

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

shortcode 2022. 9. 13. 22:33
반응형

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

번호에서 미미한 후행 제로를 삭제하는 표준 API 호출을 놓쳤습니까?

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

Number.toFixed()그리고.Number.toPrecision()내가 찾던 게 아니야

저도 비슷한 예를 하나 들자면.toFixed()패딩이 필요없을 땐 필요없었어요그래서 parse Float을 to Fixed와 함께 사용하게 되었습니다.

패딩 없이 고정

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;

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

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

나는 처음에 마티 라이라와 게리의 답을 조합해서 사용했다.

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')

위와 같은 결과가 됩니다.

toFixedmethod는 필요에 따라 적절한 반올림을 수행합니다.또한 항상 이상적인 것은 아닌 후행 0을 추가합니다.

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

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

반환값을 수치로 캐스트하면 후행 제로는 폐기됩니다.이것은 반올림 또는 잘라내기 계산을 하는 것보다 간단한 방법입니다.

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

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

이렇게 1을 곱하면 어떨까요?

var x = 1.234000*1; // becomes 1.234

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

기본적으로 동일한 요구 사항을 가지고 있었는데, 이 기능을 위한 내장 메커니즘이 없다는 것을 알 수 있었습니다.

후행 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를 지원하고 있습니다.이 API는 언어에 민감한 문자열 비교, 숫자 포맷 및 날짜와 시각 포맷을 제공합니다.

const 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"

오래된 브라우저에서는 https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~polyfill.en을 사용할 수 있습니다.

순정규답

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

왜 아무도 안 줬을까!

부동수를 최소화할 수 있습니다.

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

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

「 」를 사용하고 toFixed(n)여기서 n > 0은 보다 단순하고 안정적인(플로트 조작 없음) 솔루션이 될 수 있습니다.

(+n).toFixed(2).replace(/(\.0+|0+)$/, '')

// 0 => 0
// 0.1234 => 0.12
// 0.1001 => 0.1

// 1 => 1
// 1.1234 => 1.12
// 1.1001 => 1.1

// 100 => 100
// 100.1234 => 100.12
// 100.1001 => 100.1

: PS를 사용하는 : ★★★★★★★★★★★★★★★★★★★★★★★★★★★」toFixed(0) no 「 」가 됩니다.replace요합니니다다

장고가 텍스트 필드에 십진수 유형 값을 표시할 때도 이 문제를 해결해야 했습니다.예: '1'이 값인 경우.'1.00000000'으로 표시됩니다.'1.23'이 값이면 '1.23000000'이 표시됩니다('10진수_place' 설정이 8인 경우).

parse Float은 동일한 값을 반환하지 않을 수 있기 때문에 사용할 수 없었습니다.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;
}

이 솔루션들 중 어떤 것도 아주 적은 수에도 효과가 없었습니다.http://numeraljs.com/에서 해결해 주셨어요.

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

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

s 숫자 문자열 예: 숫자 문자열 표현)을 사용합니다..toFixed(digits) 숫자(또는 다른 수단)의 방법, 그리고 나서 유의미한 후행 제로(trailing zero)를 제거한다.s다음 중 하나:

s.replace(/(\.0*|(?<=(\..*))0*)$/, '')

/**********************************
 * Results for various values of s:
 **********************************
 *
 * "0" => 0
 * "0.000" => 0
 * 
 * "10" => 10
 * "100" => 100
 * 
 * "0.100" => 0.1
 * "0.010" => 0.01
 * 
 * "1.101" => 1.101
 * "1.100" => 1.1
 * "1.100010" => 1.10001
 * 
 * "100.11" => 100.11
 * "100.10" => 100.1
 */

의 정규 표현은replace()다음에 설명하겠습니다.

  • in에주 the 에 .|"표현 "OR"을 합니다.replace()는 메메 from from에서 됩니다.s 가능한 중 하나로 수 있는 서브스트링(\.0*)$를 or로 ((?<=(\..*))0*)$syslog.syslog.
  • (\.0*)$하며 regex의 도 일치하지 .s 이런 수 있습니다.0.0 ).0되었습니다).1.0 ).0되었습니다).0.000 ).000 & removed)이 있기 의 이 is match & removed이면 와 닷 됩니다).
  • ((?<=(\..*))0*)$부품은 후속 0(연속되는 후속 0이 시작되기 전에 점 기호 뒤에 임의의 수의 기호 뒤에 위치함)만 일치합니다., 이런 것들이 있을 수 .0.100 (비밀(이행)00되었습니다).0.010 (마지막)0됩니다.「 」 、 「 」 、 「 」에 해 주세요.0.01「 룩 어설션 「긍정적 룩 어설션」)으로 인해 하지 않는다.으로 인해 부품이 전혀 일치하지 않습니다.(?<=(\..*))앞에 0*이 에서) (regex의 'regex'는1.100010 (마지막)0「 」 「 」
  • 식의 두 부분이 모두 일치하지 않으면 삭제되지 않습니다., 이런 것들이 있을 수 .100 ★★★★★★★★★★★★★★★★★」100.11따라서 입력에 후행 제로가 없는 경우 변경되지 않습니다.

기타 사용.toFixed(digits)(아래 예에서는 리터럴값 '1000.1010'이 사용되고 있습니다만, 그 대신 변수를 상정할 수 있습니다).

let digits = 0; // Get `digits` from somewhere, for example: user input, some sort of config, etc.

(+"1000.1010").toFixed(digits).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000'

(+"1000.1010").toFixed(digits = 1).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.1'


(+"1000.1010").toFixed(digits = 2).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.1'


(+"1000.1010").toFixed(digits = 3).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.101'


(+"1000.1010").toFixed(digits = 4).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.101'


(+"1000.1010").toFixed(digits = 5).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.101'

(+"1000.1010").toFixed(digits = 10).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.101'

의 정규 .replace()다음 사이트를 방문하실 수 있습니다.

후행 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이 아닌 경우 루프를 종료합니다.
마지막 문자까지 업데이트된 문자열이 부동 소수점일 경우 루프가 종료됩니다.

어떤 이유로든 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;
}

방법은 다음과 같습니다.

parseFloat(number.toString());

이것은 TypeScript 버그에도 도움이 되는 회피책입니다.특정 상황에서 번호를 문자열로 변경하는 버그입니다.

오류에 '수치 오류'를 사용할 수 .Intl.NumberFormat ★★★★★★★★★★★★★★★★★」Number.toLocaleString()

new Intl.NumberFormat().format(0.0100) // "0.01"
new Intl.NumberFormat().format(0.010000000000001) // "0.01"
new Intl.NumberFormat().format(0.009999999999999) // "0.01"
console.log((0.0100).toLocaleString()) // "0.01"
console.log((0.010000000000001).toLocaleString()) // "0.01"
console.log((0.009999999999999).toLocaleString()) // "0.01"

그래서 네가 원하는 건

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

.string 그냥 .해보세요.Number().

var x  = 1.234000, // to become 1.234
    y  = 1.234001, // stays 1.234001
    x_ = Number(x),
    y_ = Number(y);

console.log(x_,y_);

무의미함을 쓴 입니다.zeros, decimals, and spaces beginning and end「 」 「 」 、 「 」 。

const rxInsignificant = /^[\s0]+|(?<=\..*)[\s0.]+$|\.0+$|\.$/gm;

let ary = [
"001.230",
"2.",
"3.00",
"1000",
" 0000000000000010000.10000000000000000000000  "];

ary.forEach((str)=>
{
  console.log(`"${str}" becomes "${str.replace(rxInsignificant,'')}"`);
});

아쉽게도 Safari는 정규 표현에서 뒤처진 2018년 사양을 아직 지원하지 않습니다.이 문제에 대한 미해결 버그 보고는 2017년 7월 28일부터 있었습니다.

좋은 소식은 파이어폭스와 모든 크롬 파생 제품에서 룩 이면이 작동한다는 것이다.Safari가 이 컴플라이언스에 대한 요청을 더 많이 받고 이 표준을 곧 구현하기를 바랍니다.

그동안 이 함수는 뒤를 돌아보지 않고 동일한 작업을 수행하기 위해 작성했습니다.

function createRemoveInsignificantFunction()
{
  const rxLeadingZeros = /^[\s0]+/;
  const rxEndingZeros = /[\s0]+$/;
  function removeInsignificant(str)
  {
    str = str.replace(rxLeadingZeros,'');
    let ary = str.split('.');
    if (ary.length > 1)
    {
      ary[1] = ary[1].replace(rxEndingZeros,'');
      if (ary[1].length === 0)
      {
        return ary[0];
      }
      else
      {
        return ary[0] + '.' + ary[1];
      }         
    }
    return str;
  }
  return removeInsignificant;
}
let removeInsignificant = createRemoveInsignificantFunction();
let ary = [
"001.230",
"2.",
"3.00",
"1000",
" 0000000000000010000.10000000000000000000000  "];
ary.forEach((str)=>
{
  console.log(`"${str}" becomes "${removeInsignificant(str)}"`);
});

시간이 좀 더 있을 때 어떻게 하면 뒷모습이 없는 하나의 정규 표현으로 이 일을 해낼 수 있을지 생각해보고 싶습니다.아래 댓글로 저를 앞서주시면 감사하겠습니다.

모든 답변과 코멘트를 읽은 후 다음과 같이 결론을 내렸습니다.

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;

바로 그겁니다.

저의 솔루션은 다음과 같습니다.

export const floatToStr = (f, ndigit = 2) => {
    const str = f.toFixed(ndigit)
    return ndigit
        ? str
            .replace(/0*$/g, '')
            .replace(/\.$/, '')
        : str
}

생각할 수 있는 해결책은 다음과 같습니다.

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

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

다음 기능은 당신이 원하는 기능에 가깝다고 생각합니다.나는 나의 지원서를 위해 그것을 썼다.항상 후행 0이 없는 표준 표기법으로 출력됩니다.당신이 원하지 않을 수도 있지만, 당신이 원한다면 편집할 수 있는 몇 가지 것들.항상 최소 1개의 소수점(예: 5=> "5.0")을 반환합니다.소수점 이하도 10개까지로 제한됩니다.가이드로 사용하세요.

const toDecimalStr(value)=>{
  let str=value.toFixed(10).replace(/([0]+)$/,"");
  try {
    if (str.endsWith(".")) str+='0';
  } catch (e) {
    str+='0';
  }
  return str;
}

모든 게 다 끝나는 건 아니고 제가 게을러서 그런 거예요

언급URL : https://stackoverflow.com/questions/3612744/remove-insignificant-trailing-zeros-from-a-number

반응형