web-dev-qa-db-ja.com

数字から意味のない末尾のゼロを削除しますか?

数値から末尾の無意味なゼロを削除する標準のAPI呼び出しを見逃していませんか?

例.

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

Number.toFixed()とNumber.toPrecision()は、私が探しているものとはまったく異なります。

128
Steven

文字列に変換すると、末尾のゼロは表示されません。ゼロは、文字列ではなく数値として作成されたため、最初の変数には格納されません。

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

必要に応じて.toFixed()を使用したいという似たようなインスタンスがありましたが、そうでないときはパディングが必要ではありませんでした。そのため、私はparseFloatをtoFixedと組み合わせて使用​​することになりました。

toFiddinged without padding

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

後続のゼロで数字を定義しても、それらは削除されるためです。

var n = 1.23000;
 // n == 1.23;
191
Gary

最初に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」(実行時エラーなし)

更新:これはゲイリーの新しいバージョンです(コメントを参照):

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

これにより、上記と同じ結果が得られます。

24
w00t

toFixedメソッドは、必要に応じて適切な丸めを行います。また、末尾のゼロも追加されますが、これは常に理想的ではありません。

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

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

戻り値を数値にキャストすると、末尾のゼロは削除されます。これは、独自の丸めまたは切り捨ての計算を行うよりも簡単なアプローチです。

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

+(4).toFixed(2);
//-> 4
15
C. J.

Djangoが10進数型の値をテキストフィールドに表示しているときにも、この問題を解決する必要がありました。例えば。 「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;
}
6
megasnort

純粋な正規表現の答え

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

なぜだれも与えなかったのだろうか!

6
João Costa

基本的に同じ要件があり、この機能には組み込みのメカニズムがないことがわかりました。

末尾のゼロをトリミングすることに加えて、ユーザーの現在のロケール(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国際化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"

古いブラウザの場合、次のポリフィルを使用できます。 https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en

5
dperish

このようなものを掛けるだけではどうですか?

var x = 1.234000*1; // becomes 1.234

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

これらの解決策のどれも、私にとっては非常に小さな数ではうまくいきませんでした。 http://numeraljs.com/ これを解決してくれました。

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

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

これを試して、浮動小数点数を小さくすることができます

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

//output n = 0; 
// n = 3.14000; --> n = 3.14;
3
Amit Panasara

何らかの理由でフロートを使用できない場合(マネーフロートなど)、すでに正しい数値を表す文字列から開始している場合は、このソリューションが便利です。数値を表す文字列を、末尾のゼロなしの数値を表す文字列に変換します。

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;
}
1
BennyHilarious

末尾のゼロを削除する必要がありましたが、少なくとも2つの小数、含むゼロを保持します。
作業している数字は、.toFixed(6)によって生成された6個の10進数文字列です。

期待される結果:

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

論理:

文字列の最後の文字がゼロの場合、ループ関数を実行します。
最後の文字を削除し、文字列変数を更新します。
更新された文字列の最後の文字がゼロでない場合、ループを終了します。
最後の文字の3番目から3番目の文字列が浮動小数点である場合、ループを終了します。

0
Kevin H.

すべての答えとコメントを読んだ後、私はこれで終わった:

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
ed1nh0

考えられる解決策は次のとおりです。

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

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