数値から末尾の無意味なゼロを削除する標準のAPI呼び出しを見逃していませんか?
例.
var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001
Number.toFixed()とNumber.toPrecision()は、私が探しているものとはまったく異なります。
文字列に変換すると、末尾のゼロは表示されません。ゼロは、文字列ではなく数値として作成されたため、最初の変数には格納されません。
var n = 1.245000
var noZeroes = n.toString() // "1.245"
必要に応じて.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;
最初にmatti-lyraとgaryの回答を組み合わせて使用しました。
r=(+n).toFixed(4).replace(/\.0+$/,'')
結果:
やや問題のあるケースは0.10001です。私はこの長いバージョンを使用することになりました:
r = (+n).toFixed(4);
if (r.match(/\./)) {
r = r.replace(/\.?0+$/, '');
}
更新:これはゲイリーの新しいバージョンです(コメントを参照):
r=(+n).toFixed(4).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1')
これにより、上記と同じ結果が得られます。
toFixed
メソッドは、必要に応じて適切な丸めを行います。また、末尾のゼロも追加されますが、これは常に理想的ではありません。
(4.55555).toFixed(2);
//-> "4.56"
(4).toFixed(2);
//-> "4.00"
戻り値を数値にキャストすると、末尾のゼロは削除されます。これは、独自の丸めまたは切り捨ての計算を行うよりも簡単なアプローチです。
+(4.55555).toFixed(2);
//-> 4.56
+(4).toFixed(2);
//-> 4
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;
}
純粋な正規表現の答え
n.replace(/(\.[0-9]*[1-9])0+$|\.0*$/,'$1');
なぜだれも与えなかったのだろうか!
基本的に同じ要件があり、この機能には組み込みのメカニズムがないことがわかりました。
末尾のゼロをトリミングすることに加えて、ユーザーの現在のロケール(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
このようなものを掛けるだけではどうですか?
var x = 1.234000*1; // becomes 1.234
var y = 1.234001*1; // stays as 1.234001
これらの解決策のどれも、私にとっては非常に小さな数ではうまくいきませんでした。 http://numeraljs.com/ これを解決してくれました。
parseFloat(0.00000001.toFixed(8));
// 1e-8
numeral(0.00000001).format('0[.][00000000]');
// "0.00000001"
これを試して、浮動小数点数を小さくすることができます
var n = 0.0000;
n = parseFloat(n.toString());
//output n = 0;
// n = 3.14000; --> n = 3.14;
何らかの理由でフロートを使用できない場合(マネーフロートなど)、すでに正しい数値を表す文字列から開始している場合は、このソリューションが便利です。数値を表す文字列を、末尾のゼロなしの数値を表す文字列に変換します。
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;
}
末尾のゼロを削除する必要がありましたが、少なくとも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番目の文字列が浮動小数点である場合、ループを終了します。
すべての答えとコメントを読んだ後、私はこれで終わった:
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;
それでおしまい。
考えられる解決策は次のとおりです。
var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001
eval(x) --> 1.234
eval(y) --> 1.234001