小数点以下 2 桁まで丸めたいのですが、必要な場合のみです。
入力:
10
1.7777777
9.1
出力:
10
1.78
9.1
JavaScriptでこれを行うにはどうすればよいですか?
小数点以下 2 桁まで丸めたいのですが、必要な場合のみです。
入力:
10
1.7777777
9.1
出力:
10
1.78
9.1
JavaScriptでこれを行うにはどうすればよいですか?
使用Math.round()
:
Math.round(num * 100) / 100
または、より具体的に、1.005 ラウンドなどを正しく行うには、 Number.EPSILONを使用します。
Math.round((num + Number.EPSILON) * 100) / 100
値がテキストタイプの場合:
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 * 100)/100 // 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
注:これは、すべての人にとって普遍的なソリューションではありません。いくつかの異なる丸めアルゴリズムがあり、要件に応じて、実装が異なる場合があります。https://en.wikipedia.org/wiki/Rounding
解決策2は、フロントエンドの計算を回避し、バックエンドサーバーから丸められた値を取得することです。
編集:別の可能な解決策。これも防弾ではありません。
Math.round((num + Number.EPSILON) * 100) / 100
場合によっては、1.3549999999999998のように数値を四捨五入すると、誤った結果が返されることがあります。1.35である必要がありますが、結果は1.36です。
使用できます
function roundToTwo(num) {
return +(Math.round(num + "e+2") + "e-2");
}
これはMDNで見つけました。彼らの方法は、言及された 1.005 の問題を回避します。
roundToTwo(1.005)
1.01
roundToTwo(10)
10
roundToTwo(1.7777777)
1.78
roundToTwo(9.1)
9.1
roundToTwo(1234.5678)
1234.57
You should use:
Math.round( num * 100 + Number.EPSILON ) / 100
No one seems to be aware of Number.EPSILON
.
Also it's worth noting that this is not a JavaScript weirdness like some people stated.
That is simply the way floating point numbers works in a computer. Like 99% of programming languages, JavaScript doesn't have home made floating point numbers; it relies on the CPU/FPU for that. A computer uses binary, and in binary, there isn't any numbers like 0.1
, but a mere binary approximation for that. Why? For the same reason than 1/3 cannot be written in decimal: its value is 0.33333333... with an infinity of threes.
Here come Number.EPSILON
. That number is the difference between 1 and the next number existing in the double precision floating point numbers. That's it: There is no number between 1
and 1 + Number.EPSILON
.
EDIT:
As asked in the comments, let's clarify one thing: adding Number.EPSILON
is relevant only when the value to round is the result of an arithmetic operation, as it can swallow some floating point error delta.
It's not useful when the value comes from a direct source (e.g.: literal, user input or sensor).
EDIT (2019):
Like @maganap and some peoples have pointed out, it's best to add Number.EPSILON
before multiplying:
Math.round( ( num + Number.EPSILON ) * 100 ) / 100
EDIT (december 2019):
Lately, I use a function similar to this one for comparing numbers epsilon-aware:
const ESPILON_RATE = 1 + Number.EPSILON ;
const ESPILON_ZERO = Number.MIN_VALUE ;
function epsilonEquals( a , b ) {
if ( Number.isNaN( a ) || Number.isNaN( b ) ) {
return false ;
}
if ( a === 0 || b === 0 ) {
return a <= b + EPSILON_ZERO && b <= a + EPSILON_ZERO ;
}
return a <= b * EPSILON_RATE && b <= a * EPSILON_RATE ;
}
My use-case is an assertion + data validation lib I'm developing for many years.
In fact, in the code I'm using ESPILON_RATE = 1 + 4 * Number.EPSILON
and EPSILON_ZERO = 4 * Number.MIN_VALUE
(four times the epsilon), because I want an equality checker loose enough for cumulating floating point error.
So far, it looks perfect for me. I hope it will help.
この質問は複雑です。
roundTo2DP(num)
float を引数として取り、小数点以下 2 桁に丸められた値を返す関数 があるとします。これらの各式は何に評価されるべきですか?
roundTo2DP(0.014999999999999999)
roundTo2DP(0.0150000000000000001)
roundTo2DP(0.015)
「明らかな」答えは、最初の例は 0.01 に丸める必要がある (0.02 よりも 0.01 に近いため) 一方で、他の 2 つは 0.02 に丸める必要がある (0.0150000000000000001 は 0.01 よりも 0.02 に近いため、0.015 はちょうど中間にあるため) ということです。そのような数値は切り上げられるという数学的な規則があります)。
お察しのとおり、これらの明白な答えを与えるために を実装するroundTo2DP
ことはおそらく不可能です。これは、渡される 3 つの数値がすべて同じ numberであるためです。IEEE 754 2 進浮動小数点数 (JavaScript で使用される種類) は、ほとんどの非整数を正確に表すことができないため、上記の 3 つの数値リテラルはすべて、有効な浮動小数点数に近い値に丸められます。この数字は、たまたま、まさに
0.01499999999999999944488848768742172978818416595458984375
これは、0.02 よりも 0.01 に近いです。
ブラウザ コンソール、ノード シェル、またはその他の JavaScript インタープリタで、3 つの数値がすべて同じであることを確認できます。それらを比較するだけです:
> 0.014999999999999999 === 0.0150000000000000001
true
したがって、 を書くm = 0.0150000000000000001
と、最終的に得られる の正確な値m
0.01
はよりも に近くなり0.02
ます。それでも、m
文字列に変換すると...
> var m = 0.0150000000000000001;
> console.log(String(m));
0.015
> var m = 0.014999999999999999;
> console.log(String(m));
0.015
... 0.015 が得られました。これは 0.02 に丸められるはずであり、これらの数値はすべて正確に等しいと前に述べた 56 桁の数値ではありません。では、これは何の暗黒魔法ですか?
答えは、セクション7.1.12.1: ToString applied to the Number typeの ECMAScript 仕様にあります。ここでは、数値mを文字列に変換するための規則が規定されています。重要な部分はポイント 5 で、整数sが生成され、その数字がmの String 表現で使用されます。
n 、k、およびsは、k ≥ 1、10 k -1 ≤ s < 10 k 、 s × 10 n - kのNumber 値がm、kが可能な限り小さい整数であるとします。k はs の10 進数表現の桁数であること、sは 10 で割り切れないこと、およびs の最下位桁は必ずしもこれらの基準によって一意に決定されるとは限らないことに注意してください。
ここで重要なのは、「kはできるだけ小さい」という要件です。その要件が意味するものは、 Number が与えられたm
場合、 の値は、という要件を満たしながら、可能な限り少ない桁数String(m)
でなければならないという要件です。がすでにわかっているので、なぜが真でなければならないかは明らかです。Number(String(m)) === m
0.015 === 0.0150000000000000001
String(0.0150000000000000001) === '0.015'
もちろん、この議論のどれも、何が返されるroundTo2DP(m)
べきかを直接答えていません。の正確な値m
が 0.01499999999999999944488848768742172978818416595458984375 であるが、その文字列表現が '0.015' である場合、小数点以下 2 桁に丸めたとき、数学的に、実際的に、哲学的に、またはその他何であっても、正しい答えは何ですか?
これに対する唯一の正解はありません。ユースケースによって異なります。次の場合は、文字列表現を尊重し、切り上げたいと思うでしょう。
一方、値が本質的に連続したスケールからのものである場合 (たとえば、センサーからの読み取り値である場合) は、おそらくバイナリ浮動小数点値を尊重し、切り捨てたいと思うでしょう。
これら 2 つのアプローチには、異なるコードが必要です。Number の文字列表現を尊重するために、学校で使用したのと同じアルゴリズムを使用して、数字ごとに文字列表現に直接作用する独自の丸めを (かなり微妙なコードを使用して) 実装できます。丸め方を教わりました。以下は、小数点以下の末尾のゼロを削除することにより、「必要な場合にのみ」数値を小数点以下 2 桁まで表すという OP の要件を尊重する例です。もちろん、正確なニーズに合わせて微調整する必要があるかもしれません。
/**
* Converts num to a decimal string (if it isn't one already) and then rounds it
* to at most dp decimal places.
*
* For explanation of why you'd want to perform rounding operations on a String
* rather than a Number, see http://stackoverflow.com/a/38676273/1709587
*
* @param {(number|string)} num
* @param {number} dp
* @return {string}
*/
function roundStringNumberWithoutTrailingZeroes (num, dp) {
if (arguments.length != 2) throw new Error("2 arguments required");
num = String(num);
if (num.indexOf('e+') != -1) {
// Can't round numbers this large because their string representation
// contains an exponent, like 9.99e+37
throw new Error("num too large");
}
if (num.indexOf('.') == -1) {
// Nothing to do
return num;
}
var parts = num.split('.'),
beforePoint = parts[0],
afterPoint = parts[1],
shouldRoundUp = afterPoint[dp] >= 5,
finalNumber;
afterPoint = afterPoint.slice(0, dp);
if (!shouldRoundUp) {
finalNumber = beforePoint + '.' + afterPoint;
} else if (/^9+$/.test(afterPoint)) {
// If we need to round up a number like 1.9999, increment the integer
// before the decimal point and discard the fractional part.
finalNumber = Number(beforePoint)+1;
} else {
// Starting from the last digit, increment digits until we find one
// that is not 9, then stop
var i = dp-1;
while (true) {
if (afterPoint[i] == '9') {
afterPoint = afterPoint.substr(0, i) +
'0' +
afterPoint.substr(i+1);
i--;
} else {
afterPoint = afterPoint.substr(0, i) +
(Number(afterPoint[i]) + 1) +
afterPoint.substr(i+1);
break;
}
}
finalNumber = beforePoint + '.' + afterPoint;
}
// Remove trailing zeroes from fractional part before returning
return finalNumber.replace(/0+$/, '')
}
使用例:
> roundStringNumberWithoutTrailingZeroes(1.6, 2)
'1.6'
> roundStringNumberWithoutTrailingZeroes(10000, 2)
'10000'
> roundStringNumberWithoutTrailingZeroes(0.015, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes('0.015000', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes(1, 1)
'1'
> roundStringNumberWithoutTrailingZeroes('0.015', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes(0.01499999999999999944488848768742172978818416595458984375, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes('0.01499999999999999944488848768742172978818416595458984375', 2)
'0.01'
上記の関数は、入力した数値が誤って丸められるのをユーザーが目撃するのを避けるためにおそらく使用したいものです。
(代わりに、まったく異なる実装で同様に動作する関数を提供するround10ライブラリを試すこともできます。)
しかし、2 番目の種類の数値 (連続スケールから取得した値) がある場合はどうなるでしょうか。小数点以下の桁数が少ないおおよその小数表現の方が、小数点以下の桁数が多いものよりも正確であると考える理由はありません。その場合、文字列表現を尊重したくありません。なぜなら、その表現 (仕様で説明されているように) はすでに丸められているからです。「0.014999999...375 は 0.015 に切り上げられ、0.02 に切り上げられるので、0.014999999...375 は 0.02 に切り上げられる」という間違いを犯したくありません。
toFixed
ここでは、組み込みメソッドを簡単に使用できます。Number()
によって返された Stringを呼び出すと、 toFixed
String 表現に末尾のゼロがない Number が得られることに注意してください (JavaScript が Number の String 表現を計算する方法のおかげで、この回答の前半で説明しました)。
/**
* Takes a float and rounds it to at most dp decimal places. For example
*
* roundFloatNumberWithoutTrailingZeroes(1.2345, 3)
*
* returns 1.234
*
* Note that since this treats the value passed to it as a floating point
* number, it will have counterintuitive results in some cases. For instance,
*
* roundFloatNumberWithoutTrailingZeroes(0.015, 2)
*
* gives 0.01 where 0.02 might be expected. For an explanation of why, see
* http://stackoverflow.com/a/38676273/1709587. You may want to consider using the
* roundStringNumberWithoutTrailingZeroes function there instead.
*
* @param {number} num
* @param {number} dp
* @return {number}
*/
function roundFloatNumberWithoutTrailingZeroes (num, dp) {
var numToFixedDp = Number(num).toFixed(dp);
return Number(numToFixedDp);
}
考慮.toFixed()
してください.toPrecision()
:
を使用できます.toFixed(NumberOfDecimalPlaces)
。
var str = 10.234.toFixed(2); // => '10.23'
var number = Number(str); // => 10.23
正確な丸め方法。ソース:モジラ
(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
これを行う簡単な方法は次のとおりです。
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);
}
これはあなたを助けるかもしれません:
var result = Math.round(input*100)/100;
詳細については、このリンクをご覧ください。
+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12
(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12
最も簡単な方法は、toFixed を使用してから、Number 関数を使用して末尾のゼロを削除することです。
const number = 15.5;
Number(number.toFixed(2)); // 15.5
const number = 1.7777777;
Number(number.toFixed(2)); // 1.78
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
それはあなたのために働くかもしれません、
Math.round(num * 100)/100;
toFixed と round の違いを知る。Math.round(num) vs num.toFixed(0) と browser inconsistencies をご覧ください。
これは最もシンプルでエレガントなソリューションです (そして私は世界一です;):
function roundToX(num, X) {
return +(Math.round(num + "e+"+X) + "e-"+X);
}
//roundToX(66.66666666,2) => 66.67
//roundToX(10,2) => 10
//roundToX(10.904,2) => 10.9
フォールバック値を使用した最新の構文の代替
const roundToX = (num = 0, X = 20) => +(Math.round(num + `e${X}`) + `e-${X}`)
var roundUpto = function(number, upto){
return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);
toFixed(2)
ここで 2 は、この数値を丸めたい桁数です。
プロトタイプメソッドは次のとおりです。
Number.prototype.round = function(places){
places = Math.pow(10, places);
return Math.round(this * places)/places;
}
var yournum = 10.55555;
yournum = yournum.round(2);
最も簡単な方法:
+num.toFixed(2)
それを文字列に変換してから、整数/浮動小数点数に戻します。
この「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
多くの 0 を処理しないようにするには、次のバリアントを使用します。
Math.round(num * 1e2) / 1e2
d3 ライブラリを既に使用している場合は、強力な数値書式設定ライブラリがあります: https://github.com/mbostock/d3/wiki/Formatting
具体的な丸めはこちら: https://github.com/mbostock/d3/wiki/Formatting#d3_round
あなたの場合、答えは次のとおりです。
> d3.round(1.777777, 2)
1.78
> d3.round(1.7, 2)
1.7
> d3.round(1, 2)
1
より単純な ES6 の方法は次のとおりです。
const round = (x, n) =>
Number(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.12
parseFloat("1.555").toFixed(2); // 1.56 ではなく 1.55 を返します。
コンピューターには 1.555 の正確な表現が存在しないため、1.55 は絶対的に正しい結果です。1.555 を読み取る場合、最も近い可能な値 = 1.55499999999999994 (64 ビット浮動小数点数) に丸められます。この数値を toFixed(2) で丸めると、1.55 になります。
ここで提供される他のすべての関数は、入力が 1.55499999999999 の場合、エラー結果を返します。
解決策: 数値を切り上げる (より正確には、0 から四捨五入する) ために、スキャンする前に数字 "5" を追加します。これは、数値が実際に浮動小数点 (小数点がある) である場合にのみ行ってください。
parseFloat("1.555"+"5").toFixed(2); // Returns 1.56
これは私にとってはうまくいきました(TypeScript):
round(decimal: number, decimalPoints: number): number{
let roundedValue = Math.round(decimal * Math.pow(10, decimalPoints)) / Math.pow(10, decimalPoints);
console.log(`Rounded ${decimal} to ${roundedValue}`);
return roundedValue;
}
// Sample output:
Rounded 18.339840000000436 to 18.34
Rounded 52.48283999999984 to 52.48
Rounded 57.24612000000036 to 57.25
Rounded 23.068320000000142 to 23.07
Rounded 7.792980000000398 to 7.79
Rounded 31.54157999999981 to 31.54
Rounded 36.79686000000004 to 36.8
Rounded 34.723080000000124 to 34.72
Rounded 8.4375 to 8.44
Rounded 15.666960000000074 to 15.67
Rounded 29.531279999999924 to 29.53
Rounded 8.277420000000006 to 8.28
私たちを導く
let round= x=> ( x+0.005 - (x+0.005)%0.01 +'' ).replace(/(\...)(.*)/,'$1');
// for case like 1.384 we need to use regexp to get only 2 digits after dot
// and cut off machine-error (epsilon)
console.log(round(10));
console.log(round(1.7777777));
console.log(round(1.7747777));
console.log(round(1.384));
多くの答えがあることは知っていますが、それらのほとんどは特定のケースで副作用があります。
副作用のない最も簡単で最短の解決策は次のとおりです。
Number((2.3456789).toFixed(2)) // 2.35
適切に丸められ、文字列ではなく数値が返されます
console.log(Number((2.345).toFixed(2))) // 2.35
console.log(Number((2.344).toFixed(2))) // 2.34
console.log(Number((2).toFixed(2))) // 2
console.log(Number((-2).toFixed(2))) // -2
console.log(Number((-2.345).toFixed(2))) // -2.35
console.log(Number((2.345678).toFixed(3))) // 2.346
また、Math.round 関数をオーバーライドして丸めを正しく行い、小数のパラメーターを追加して、Math.round(Number, Decimals) のように使用することもできます。これは、組み込みコンポーネント Math.round をオーバーライドし、別のプロパティを与えることに注意してください。
var round = Math.round;
Math.round = function (value, decimals) {
decimals = decimals || 0;
return Number(round(value + 'e' + decimals) + 'e-' + decimals);
}
次に、次のように簡単に使用できます。
Math.round(1.005, 2);
jQuery .number プラグインを使用してみてください:
var number = 19.8000000007;
var res = 1 * $.number(number, 2);
最短かつ完全な答えは次のとおりです。
function round(num, decimals) {
var n = Math.pow(10, decimals);
return Math.round( (n * num).toFixed(decimals) ) / n;
};
これは、1.01 を返すサンプル ケース 1.005 にも対応します。
小数点以下を四捨五入するにはpos
(小数点なしを含む)、次のようにします。Math.round(num * Math.pow(10,pos)) / Math.pow(10,pos)
var console = {
log: function(s) {
document.getElementById("console").innerHTML += s + "<br/>"
}
}
var roundDecimals=function(num,pos) {
return (Math.round(num * Math.pow(10,pos)) / Math.pow(10,pos) );
}
//https://en.wikipedia.org/wiki/Pi
var pi=3.14159265358979323846264338327950288419716939937510;
for(var i=2;i<15;i++) console.log("pi="+roundDecimals(pi,i));
for(var i=15;i>=0;--i) console.log("pi="+roundDecimals(pi,i));
<div id="console" />
これは、「切り上げ」を行うために思いついた関数です。JavaScript の不正確な乗算を補うために double Math.round を使用したので、1.005 は 1.01 として正しく丸められます。
function myRound(number, decimalplaces){
if(decimalplaces > 0){
var multiply1 = Math.pow(10,(decimalplaces + 4));
var divide1 = Math.pow(10, decimalplaces);
return Math.round(Math.round(number * multiply1)/10000 )/divide1;
}
if(decimalplaces < 0){
var divide2 = Math.pow(10, Math.abs(decimalplaces));
var multiply2 = Math.pow(10, Math.abs(decimalplaces));
return Math.round(Math.round(number / divide2) * multiply2);
}
return Math.round(number);
}
前述の回答に基づいて、私のアプローチを共有したかっただけです。
指定された数値を指定された小数点以下の桁数に丸める関数を作成しましょう。
function roundWDecimals(n, decimals) {
if (!isNaN(parseFloat(n)) && isFinite(n)) {
if (typeof(decimals) == typeof(undefined)) {
decimals = 0;
}
var decimalPower = Math.pow(10, decimals);
return Math.round(parseFloat(n) * decimalPower) / decimalPower;
}
return NaN;
}
また、数値プロトタイプに新しい「丸め」メソッドを導入します。
Object.defineProperty(Number.prototype, 'round', {
enumerable: false,
value: function(decimals) {
return roundWDecimals(this, decimals);
}
});
そして、あなたはそれをテストすることができます:
function roundWDecimals(n, decimals) {
if (!isNaN(parseFloat(n)) && isFinite(n)) {
if (typeof(decimals) == typeof(undefined)) {
decimals = 0;
}
var decimalPower = Math.pow(10, decimals);
return Math.round(parseFloat(n) * decimalPower) / decimalPower;
}
return NaN;
}
Object.defineProperty(Number.prototype, 'round', {
enumerable: false,
value: function(decimals) {
return roundWDecimals(this, decimals);
}
});
var roundables = [
{num: 10, decimals: 2},
{num: 1.7777777, decimals: 2},
{num: 9.1, decimals: 2},
{num: 55.55, decimals: 1},
{num: 55.549, decimals: 1},
{num: 55, decimals: 0},
{num: 54.9, decimals: 0},
{num: -55.55, decimals: 1},
{num: -55.551, decimals: 1},
{num: -55, decimals: 0},
{num: 1.005, decimals: 2},
{num: 1.005, decimals: 2},
{num: 19.8000000007, decimals: 2},
],
table = '<table border="1"><tr><th>Num</th><th>Decimals</th><th>Result</th></tr>';
$.each(roundables, function() {
table +=
'<tr>'+
'<td>'+this.num+'</td>'+
'<td>'+this.decimals+'</td>'+
'<td>'+this.num.round(this.decimals)+'</td>'+
'</tr>'
;
});
table += '</table>';
$('.results').append(table);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="results"></div>
正数、負数、および大きな数を正しく処理する
function Round(value) {
const neat = +(Math.abs(value).toPrecision(15));
const rounded = Math.round(neat * 100) / 100;
return rounded * Math.sign(value);
}
//0.244 -> 0.24
//0.245 -> 0.25
//0.246 -> 0.25
//-0.244 -> -0.24
//-0.245 -> -0.25
//-0.246 -> -0.25
この答えは、速度に関するものです。
var precalculatedPrecisions = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10];
function round(num, _prec) {
_precision = precalculatedPrecisions[_prec]
return Math.round(num * _precision + 1e-14) / _precision ;
}
四捨五入したくない場合は、以下の関数を使用してください。
function ConvertToDecimal(num) {
num = num.toString(); // If it's not already a String
num = num.slice(0, (num.indexOf(".")) + 3); // With 3 exposing the hundredths place
alert('M : ' + Number(num)); // If you need it back as a Number
}
数値を丸めるために、この関数を作成しました。値は、文字列 (例: '1.005') または数値 1.005 で、デフォルトで 1 になります。小数を 2 に指定すると、結果は 1.01 になります。
round(value: string | number, decimals: number | string = "0"): number | null {
return +( Math.round(Number(value + "e+"+decimals)) + "e-" + decimals);
}
使用法: round(1.005, 2) // 1.01 または使用法: round('1.005', 2) //1.01
必要な場合にのみ丸めを行う方法について、誰も彼に答えを与えたとはまだ思いません。私が見る最も簡単な方法は、次のように、数値に小数があるかどうかを確認することです。
var num = 3.21;
if ( (num+"").indexOf('.') >= 0 ) { //at least assert to string first...
// whatever code you decide to use to round
}