javascript - 桁数 - typescript 小数点




小数点以下2桁までの丸め(必要な場合のみ) (20)

私は小数点以下2桁までを丸めたいが、必要な場合にのみ行う

入力:

10
1.7777777
9.1

出力:

10
1.78
9.1

JavaScriptこれを行うにはどうすればいいですか?


2017年
ネイティブコード.toFixed()使用するだけです。

number = 1.2345;
number.toFixed(2) // "1.23"

厳密で必要な場合にのみ数字を追加する必要がある場合は、 replace

number = 1; // "1"
number.toFixed(5).replace(/\.?0*$/g,'');

MarkGの答えが正しいです。 小数点以下の桁数に応じた一般的な拡張機能です。

Number.prototype.round = function(places) {
  return +(Math.round(this + "e+" + places)  + "e-" + places);
}

使用法:

var n = 1.7777;    
n.round(2); // 1.78

単体テスト:

it.only('should round floats to 2 places', function() {

  var cases = [
    { n: 10,      e: 10,    p:2 },
    { n: 1.7777,  e: 1.78,  p:2 },
    { n: 1.005,   e: 1.01,  p:2 },
    { n: 1.005,   e: 1,     p:0 },
    { n: 1.77777, e: 1.8,   p:1 }
  ]

  cases.forEach(function(testCase) {
    var r = testCase.n.round(testCase.p);
    assert.equal(r, testCase.e, 'didn\'t get right number');
  });
})

.toFixed(NumberOfDecimalPlaces)使用できます。

var str = 10.234.toFixed(2); // => '10.23'
var number = Number(str); // => 10.23

Math.round(num * 100) / 100


lodashライブラリを使用している場合は、以下のようにlodashのラウンドメソッドを使用できます。

_.round(number, precision)

例えば:

_.round(1.7777777, 2) = 1.78

あなたは以下を使用するべきです:

Math.round( num * 100 + Number.EPSILON ) / 100

誰もNumber.EPSILON知らないようです。 Number.EPSILON

また、これは一部の人々のようにJavaScriptの奇妙さではないことに注意する価値があります

それは浮動小数点数がコンピュータで動作する単純な方法です。 99%のプログラミング言語と同様に、JavaScriptには自家製の浮動小数点数がありません。 それはCPU / FPUに依存しています。 コンピュータはバイナリを使用し、バイナリでは0.1ような数字はありませんが、単なるバイナリ近似です。 どうして? 1/3と同じ理由で10進数で書くことはできません:その値は0.33333333 ...無限の3つです。

ここ数が来る。 Number.EPSILON 。 この数は、1と倍精度浮動小数点数に存在する次の数の差です。 それだけです: 1と1 +数字の間に数字はありません。 Number.EPSILON

編集:

コメントで尋ねられるように、1つのことを明確にしましょうNumber.EPSILON追加することは、浮動小数点エラーデルタをNumber.EPSILONことができるので、丸められる値が算術演算の結果である場合にのみ関係します。

値が直接的なソース(例えば、リテラル、ユーザ入力、センサ)から来た場合は役に立ちません。


この軽量ソリューションをお試しください:

function round(x, digits){
  return parseFloat(x.toFixed(digits))
}

 round(1.222,  2) ;
 // 1.22
 round(1.222, 10) ;
 // 1.222

このようなものを使用してください "parseFloat(parseFloat(value).toFixed(2))"

parseFloat(parseFloat("1.7777777").toFixed(2))-->1.78 
parseFloat(parseFloat("10").toFixed(2))-->10 
parseFloat(parseFloat("9.1").toFixed(2))-->9.1


これを行う簡単な方法は次のとおりです。

Math.round(value * 100) / 100

あなたは先に進み、あなたのためにそれを行うために別の機能を作りたいかもしれません:

function roundToTwo(value) {
    return(Math.round(value * 100) / 100);
}

次に、値を渡します。

2番目のパラメータを追加することで任意の小数点以下の桁数に丸めることができます。

function myRound(value, places) {
    var multiplier = Math.pow(10, places);

    return (Math.round(value * multiplier) / multiplier);
}

よりシンプルなES6方法は

const round = (x, n) => 
  parseFloat(Math.round(x * Math.pow(10, n)) / Math.pow(10, n)).toFixed(n);

このパターンは要求された精度も返します。

例:

round(44.7826456, 4)  // yields 44.7826
round(78.12, 4)       // yields 78.1200

プロトタイプメソッドは次のとおりです。

Number.prototype.round = function(places){
    places = Math.pow(10, places); 
    return Math.round(this * places)/places;
}

var yournum = 10.55555;
yournum = yournum.round(2);

値がテキストタイプの場合:

parseFloat("123.456").toFixed(2);

値が数値の場合:

var numb = 123.23454;
numb = numb.toFixed(2);

1.5のような値が出力として「1.50」を与えるという欠点がある。 @minitechによって提案された修正:

var numb = 1.5;
numb = +numb.toFixed(2);
// Note the plus sign that drops any "extra" zeroes at the end.
// It changes the result (which is a string) into a number again (think "0 + foo"),
// which means that it uses only as many digits as necessary.

それはMath.roundの方が良い解決策だと思われます。 そうではありません! 場合によっては正しく丸められません:

Math.round(1.005 * 1000)/1000 // Returns 1 instead of expected 1.01!

toFixed()も正しく丸められない場合があります(Chrome v.55.0.2883.87でテスト済み)。

例:

parseFloat("1.555").toFixed(2); // Returns 1.55 instead of 1.56.
parseFloat("1.5550").toFixed(2); // Returns 1.55 instead of 1.56.
// However, it will return correct result if you round 1.5551.
parseFloat("1.5551").toFixed(2); // Returns 1.56 as expected.

1.3555.toFixed(3) // Returns 1.355 instead of expected 1.356.
// However, it will return correct result if you round 1.35551.
1.35551.toFixed(2); // Returns 1.36 as expected.

私は、1.555は実際には裏のフロート1.55499994のようなものだからだと思います。

解決策1は、必要な丸めアルゴリズムを持つスクリプトを使用することです。たとえば、次のようにします。

function roundNumber(num, scale) {
  if(!("" + num).includes("e")) {
    return +(Math.round(num + "e+" + scale)  + "e-" + scale);
  } else {
    var arr = ("" + num).split("e");
    var sig = ""
    if(+arr[1] + scale > 0) {
      sig = "+";
    }
    return +(Math.round(+arr[0] + "e" + sig + (+arr[1] + scale)) + "e-" + scale);
  }
}

https://plnkr.co/edit/uau8BlS1cqbvWPCHJeOy?p=preview

解決策2は、フロントエンドの計算を避け、バックエンドサーバーから丸めた値を引き出すことです。


多くの0を扱わないために、この亜種を使用してください:

Math.round(num * 1e2) / 1e2

正確な丸め方法。 出典: MDN

(function(){

    /**
     * Decimal adjustment of a number.
     *
     * @param   {String}    type    The type of adjustment.
     * @param   {Number}    value   The number.
     * @param   {Integer}   exp     The exponent (the 10 logarithm of the adjustment base).
     * @returns {Number}            The adjusted value.
     */
    function decimalAdjust(type, value, exp) {
        // If the exp is undefined or zero...
        if (typeof exp === 'undefined' || +exp === 0) {
            return Math[type](value);
        }
        value = +value;
        exp = +exp;
        // If the value is not a number or the exp is not an integer...
        if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
            return NaN;
        }
        // Shift
        value = value.toString().split('e');
        value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
        // Shift back
        value = value.toString().split('e');
        return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
    }

    // Decimal round
    if (!Math.round10) {
        Math.round10 = function(value, exp) {
            return decimalAdjust('round', value, exp);
        };
    }
    // Decimal floor
    if (!Math.floor10) {
        Math.floor10 = function(value, exp) {
            return decimalAdjust('floor', value, exp);
        };
    }
    // Decimal ceil
    if (!Math.ceil10) {
        Math.ceil10 = function(value, exp) {
            return decimalAdjust('ceil', value, exp);
        };
    }
})();

例:

// Round
Math.round10(55.55, -1); // 55.6
Math.round10(55.549, -1); // 55.5
Math.round10(55, 1); // 60
Math.round10(54.9, 1); // 50
Math.round10(-55.55, -1); // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1); // -50
Math.round10(-55.1, 1); // -60
Math.round10(1.005, -2); // 1.01 -- compare this with Math.round(1.005*100)/100 above
// Floor
Math.floor10(55.59, -1); // 55.5
Math.floor10(59, 1); // 50
Math.floor10(-55.51, -1); // -55.6
Math.floor10(-51, 1); // -60
// Ceil
Math.ceil10(55.51, -1); // 55.6
Math.ceil10(51, 1); // 60
Math.ceil10(-55.59, -1); // -55.5
Math.ceil10(-59, 1); // -50

私にとってMDNは正解を出していませんでした。私はtoFixedtoFixedことを発見しました。以下はその両方の例です。

console.log(Math.round(43000 / 80000) * 100); // wrong answer

console.log(((43000 / 80000) * 100).toFixed(2)); // correct answer


MarkGとLavamantisは、受け入れられたソリューションよりもはるかに優れたソリューションを提供しました。彼らはより多くのアップホントを得ないのは残念です!

ここでMDNに基づく浮動小数点数の問題を解決するために使用する関数を示します。それはLavamantisの解決策よりもさらに一般的ですが、簡潔です。

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp  = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));

  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}

それと一緒に使う:

round(10.8034, 2);      // Returns 10.8
round(1.275, 2);        // Returns 1.28
round(1.27499, 2);      // Returns 1.27
round(1.2345678e+2, 2); // Returns 123.46

Lavamantisのソリューションと比較して、我々は行うことができます...

round(1234.5678, -2); // Returns 1200
round("123.45");      // Returns 123

このような丸めを必要に応じてのみ行うには、Number.prototype.toLocaleString()を使用するNumber.prototype.toLocaleString()があります。

myNumber.toLocaleString('en', {maximumFractionDigits:2, useGrouping:false})

これは期待通りの出力を文字列として提供します。あなたが期待しているデータ型でない場合、それらの数値を数値に変換することはできます。



+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12

(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12






decimal-point