උපරිම දශම ස්ථාන 2 ක් දක්වා (අවශ්‍ය නම් පමණක්)


2771

මම උපරිම දශම ස්ථාන 2 ක් වටා යාමට කැමතියි, නමුත් අවශ්‍ය නම් පමණි .

ආදානය:

10
1.7777777
9.1

ප්‍රතිදානය:

10
1.78
9.1

ජාවාස්ක්‍රිප්ට් හි මෙය කරන්නේ කෙසේද?


22
මම මෙතන විසඳුම් ලෙස ඉදිරිපත් කර ඇති ක්රම බොහෝ සමග වීණාවක් කර ... ඔබ සංසන්දනය කළ හැකි නිසා: වීණාවක්
dsdsdsdsd

38
කිසිවෙකු දැනුවත්ව සිටින බවක් නොපෙනේ Number.EPSILON. භාවිතා කරන්න Math.round( num * 100 + Number.EPSILON ) / 100.
cronvel

3
නව පා readers කයින් සඳහා, ඔබට නූල් වර්ගයේ ප්‍රති .ලයක් නොමැති නම් ඔබට මෙය කළ නොහැක . ඉලක්කම්වල ද්විමය අභ්‍යන්තර නිරූපණයන් මත පාවෙන ලක්ෂ්‍ය ගණිතය යන්නෙන් අදහස් කරන්නේ නිරතුරුවම දශම ලෙස නිරූපණය කළ නොහැකි සංඛ්‍යා ඇති බවයි.
වොල්ෆ්

9
oncronvel Number.EPSILONමෙහි භාවිතා කිරීමට හේතුව ඔබට පැහැදිලි කළ හැකිද ?
සන්

5
මම හාවා කුහරයෙන් බිමට වැටී මෙම පිටුවේ වඩාත් රසවත් පිළිතුරු කිහිපයක් පරීක්ෂා කළෙමි (පළමු පිටුවට පමණි). මෙන්න කෝඩපන් එකක් . ඉඟිය: පිළිතුරට වැඩි වැඩියෙන්, එය නිසි ලෙස ක්‍රියාත්මක වීමේ සම්භාවිතාව අඩු ය.
ඇඩම් ජාගෝස්

Answers:


3514

භාවිත Math.round(num * 100) / 100

සංස්කරණය කරන්න: 1.005 වටය වැනි දේ නිවැරදිව සහතික කිරීම සඳහා, අපි භාවිතා කරමු

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


395
මෙය බොහෝ අවස්ථාවන් සඳහා ක්‍රියාත්මක වන අතර, එය 1.005 සඳහා ක්‍රියා නොකරනු ඇති අතර එය 1.01 වෙනුවට 1 බවට පත්වේ
ජේම්ස්

83
@ ජේම්ස් වාව් ඇත්තෙන්ම අමුතුයි- මම ක්‍රෝම් ඩිව් කොන්සෝලය තුළ වැඩ කරන අතර 1.005 * 100 = 100.49999999999999 බව මම දනිමි. Math.round (100.49999999999999) 100 ක් දක්වා තක්සේරු කරන අතර Math.round (100.5) 101 දක්වා තක්සේරු කරයි. IE9 එකම දේ කරයි. මෙයට හේතුව ජාවාස්ක්‍රිප්ට් හි පාවෙන ලක්ෂ්‍යයේ
අමුතුකමයි

153
සරල විසඳුමක්. 2 dp සඳහා, භාවිතා කරන්න Math.round((num + 0.00001) * 100) / 100. උත්සාහ Math.round((1.005 + 0.00001) * 100) / 100කරMath.round((1.0049 + 0.00001) * 100) / 100
mrkschan

31
rmrkschan එය ක්‍රියාත්මක වන්නේ ඇයි, සහ එය සියලු සංඛ්‍යා සඳහා මෝඩද?
CMCDragonkai

86
ඔබ එය ලබා නොගන්නා අයට මෙම තාක්ෂණය පරිමාණය ලෙස හැඳින්වේ. මූලික වශයෙන් මෙහි පිළිතුර වන්නේ දශම ලක්ෂ්‍යය හරහා සංඛ්‍යා දෙකක් ගෙන ඒම පිස්සු පාවෙන ලක්ෂ්‍ය ගැටළු මඟහරවා ගැනීම සඳහා රූපය මුළු සංඛ්‍යාවක් බවට හරවා ගැනීමයි. 2dp ට පිළිතුර.
ඇලෙක්ස්_නාබු

3076

අගය පෙළ වර්ගයක් නම්:

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

සටහන: මෙය සෑම කෙනෙකුටම විශ්වීය විසඳුමක් නොවේ. විවිධ වටකුරු ඇල්ගොරිතම කිහිපයක් ඇත, ඔබේ ක්‍රියාත්මක කිරීම වෙනස් විය හැකිය, ඔබේ අවශ්‍යතා මත රඳා පවතී. https://en.wikipedia.org/wiki/Rounding

විසඳුම 2 යනු ඉදිරිපස ගණනය කිරීම් වලක්වා ගැනීම සහ පසුපස සේවාදායකයෙන් වටකුරු අගයන් ඇද ගැනීමයි.


81
මෙම (toFixed) ප්‍රවේශය හොඳයි, මා වෙනුවෙන් වැඩ කළා, නමුත් එය විශේෂයෙන් “අවශ්‍ය විට පමණක්” යන මුල් ඉල්ලීමට අනුකූල නොවේ . (එය 1.5 සිට 1.50 දක්වා වටය, එය පිරිවිතරය බිඳ දමයි.)
පර් ලුන්ඩ්බර්ග්

29
“අවශ්‍ය විටක” අවශ්‍යතාවය සඳහා මෙය කරන්න: parseFloat(number.toFixed(decimalPlaces)); erPerLundberg
Onur Yıldırım

36
parseFloat("55.555").toFixed(2)"55.55"Chrome dev කොන්සෝලය තුළ නැවත පැමිණේ .
ලෙවී බොටෙල්හෝ

22
Math.round වෙනුවට toFixed භාවිතා කිරීමෙන් කිසිදු වාසියක් නොමැත; toFixed එකම වටකුරු ගැටළු වලට මග පාදයි (ඒවා 5.555 සහ 1.005 සමඟ උත්සාහ කරන්න), නමුත් එය 500x (විහිළුවක් නැත) Math.round ට වඩා මන්දගාමී වේ ... arkMarkG පිළිතුර මෙහි වඩා නිවැරදි බව පෙනේ.
පියරේ

17
toFixed විසින් "සමහර විට" නූලක් ලබා නොදේ, එය සෑම විටම නූලක් ලබා දෙයි.
මැක්ගුවර් වී 10

465

ඔයාට පාවිච්චි කරන්න පුළුවන්

function roundToTwo(num) {    
    return +(Math.round(num + "e+2")  + "e-2");
}

මම මෙය එම්.ඩී.එන් . ඔවුන්ගේ මාර්ගය සඳහන් කළ 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

13
EdsRedsandro +(val)යනු බලහත්කාරය භාවිතා කිරීමට සමාන වේ Number(val). "ඊ -2" අංකයකට සංයුක්ත කිරීමෙන් ප්‍රති string ලයක් ලෙස නූලක් අංකයකට පරිවර්තනය කළ යුතුය.
ජැක්

41
එතැන් සිට NaN නිපදවන විශාල හා කුඩා පාවෙන සඳහා පරිස්සම් වන්න, උදා. + "1e-21 + 2" නිවැරදිව විග්‍රහ නොකෙරේ.
පියරේ

16
ඔබ 1.005 'ගැටලුව' විසඳා ඇත, නමුත් නව එකක් හඳුන්වා දී ඇත: දැන්, ක්‍රෝම් කොන්සෝලය තුළ roundToTwo(1.0049999999999999)1.01 ලෙස එළියට එයි (නොවැලැක්විය හැකි බැවින් 1.0049999999999999 == 1.005). මට පෙනෙන පරිදි ඔබ num = 1.005'පැහැදිලිවම' ටයිප් කළහොත් ඔබට ලැබෙන පාවෙන අගය 1.00 දක්වා වට විය යුතුය, මන්ද අංකයේ නිශ්චිත අගය 1.005 ට වඩා අඩුය. ඇත්ත වශයෙන්ම, '1.005' 'පැහැදිලිවම' 'නූල 1.01 දක්වා වට කළ යුතු බව මට පෙනේ. මෙහි සැබෑ නිවැරදි හැසිරීම කුමක්ද යන්න පිළිබඳව විවිධ පුද්ගලයින්ට විවිධ අදහස් ඇති බව පෙනෙන්නට තිබීම එය සංකීර්ණ වීමට හේතුවකි.
මාර්ක් අමරි

35
අතර කිසිදු (ඉපිලුම් ලක්ෂ්ය) සංඛ්යාවක් පවතින බවත් 1.0049999999999999හා 1.005ඒ නිසා නිර්වචනය විසින්, ඒ හා සමගාමීව ඔවුන් විසින් අංකය වේ. මෙය dedekind cut ලෙස හැඳින්වේ.
අස්මිසොව්

6
Z ඇස්මිසොව් හරි. අතර 1.00499 < 1.005වේ true, 1.0049999999999999 < 1.005ඇගයීමට කිරීමට false.
falconepl

146

මාර්ක්ගේ පිළිතුර නිවැරදි ය. මෙන්න ඕනෑම දශම ස්ථාන සඳහා සාමාන්‍ය දිගුවක්.

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

20
මාර්ක්ගේ පිළිතුර සමඟ පියරේ බරපතල ප්‍රශ්නයක් මතු කළේය.
dsjoerg

9
සටහන: ඔබට අංක.ප්‍රොටොටයිප් වෙනස් කිරීමට අවශ්‍ය නැතිනම් - මෙය ශ්‍රිතයක් ලෙස ලියන්න: function round(number, decimals) { return +(Math.round(number + "e+" + decimals) + "e-" + decimals); }
පිලිප් සිප්මන්

2
මෙය පුළුල් කිරීමට සිසිල් ක්‍රමයක්. දශම negative ණදැයි ඔබට පරීක්ෂා කළ හැකි අතර ඉන්වර්ටර් ඊ + සහ ඊ-. එවිට n = 115; n.round (-2); 100 නිපදවනු ඇත
ලී ලුවියර්

3
N: 1e + 19 උත්සාහ කරන්න - එය නාන්
ඩේවිඩ් ජේ

3
මෙම ඇල්ගොරිතම සැමවිටම වටයනු ඇත (ශුන්‍යයෙන් away ත් වීම වෙනුවට). එබැවින්, negative ණ සංඛ්‍යා නම්, ප්‍රතිදානය ඔබ අපේක්ෂා කළ හැකි නොවේ:(-1.005).round(2) === -1
ඇලෙක්සෙජ් කොමරොව්

125

ඔබ භාවිතා කළ යුත්තේ:

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

කිසිවෙකු දැනුවත්ව සිටින බවක් නොපෙනේ Number.EPSILON.

සමහර අය ප්‍රකාශ කළ පරිදි මෙය ජාවාස්ක්‍රිප්ට් අමුතු දෙයක් නොවන බව ද සඳහන් කිරීම වටී .

පරිගණකයක පාවෙන ලක්ෂ්‍ය සංඛ්‍යා ක්‍රියා කරන ආකාරය එයයි. ක්‍රමලේඛන භාෂාවන්ගෙන් 99% ක් මෙන්, ජාවාස්ක්‍රිප්ට් සතුව ගෙදර හැදූ පාවෙන ලක්ෂ්‍ය අංක නොමැත; එය ඒ සඳහා CPU / FPU මත රඳා පවතී. පරිගණකයක් ද්විමය භාවිතා කරන අතර ද්විමය තුළ එවැනි සංඛ්‍යා නොමැත 0.1, නමුත් ඒ සඳහා හුදෙක් ද්විමය දළ වශයෙන්. මන්ද? 1/3 ට වඩා එකම හේතුව නිසා දශමයෙන් ලිවිය නොහැක: එහි වටිනාකම 0.33333333 ... අනන්ත තුන්දෙනෙකු සමඟ.

මෙන්න එන්න Number.EPSILON. එම සංඛ්‍යාව ද්විත්ව නිරවද්‍යතාවයෙන් යුත් පාවෙන ලක්ෂ්‍ය අංකවල පවතින 1 සහ ඊළඟ සංඛ්‍යාව අතර වෙනසයි . එය එයයි: 11 + සහ 1 + අතර සංඛ්‍යාවක් නොමැත Number.EPSILON.

සංස්කරණය කරන්න:

අදහස් දැක්වීමේදී විමසා ඇති පරිදි, එක් දෙයක් පැහැදිලි කර ගනිමු: එකතු Number.EPSILONකිරීම අදාළ වන්නේ වටකුරු අගය ගණිතමය මෙහෙයුමක ප්‍රති result ලයක් වන විට පමණි, එයට යම් පාවෙන ලක්ෂ්‍ය දෝෂ ඩෙල්ටාවක් ගිල දැමිය හැකිය.

අගය සෘජු ප්‍රභවයකින් පැමිණෙන විට එය ප්‍රයෝජනවත් නොවේ (උදා: වචනාර්ථ, පරිශීලක ආදානය හෝ සංවේදකය).

සංස්කරණය කරන්න (2019):

Ag මාගනාප් සහ සමහර ජනයා පෙන්වා දී ඇති පරිදි, Number.EPSILONගුණ කිරීමට පෙර එකතු කිරීම වඩාත් සුදුසුය :

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

සංස්කරණය කරන්න (2019 දෙසැම්බර්):

මෑතකදී, එප්සිලෝන්-දැනුවත් සංඛ්‍යා සංසන්දනය කිරීම සඳහා මම මේ හා සමාන ශ්‍රිතයක් භාවිතා කරමි:

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

මගේ භාවිත අවස්ථාව මම වසර ගණනාවක් තිස්සේ සංවර්ධනය කරමින් සිටින දත්ත + වලංගු කිරීමේ ප්‍රකාශයකි .

ඇත්ත වශයෙන්ම, මම භාවිතා කරන කේතයේ ESPILON_RATE = 1 + 4 * Number.EPSILONසහ EPSILON_ZERO = 4 * Number.MIN_VALUE(එප්සිලෝන් මෙන් හතර ගුණයක්), මට අවශ්‍ය වන්නේ සමානාත්මතා පරීක්‍ෂකවරයකු පාවෙන ලක්ෂ්‍ය දෝෂ සමුච්චය කිරීමට තරම් ලිහිල් කිරීමට අවශ්‍ය නිසාය.

මෙතෙක්, එය මට පරිපූර්ණ පෙනුමක්. එය උපකාරී වනු ඇතැයි මම බලාපොරොත්තු වෙමි.


1
al පැලෝටා ඔබට එප්සිලන් ක්‍රොන්වෙල් වැනි නියම අංකයක් අර්ථ දැක්විය හැකිය
ඩැනියෙල් සැන්

3
මෙය නිවැරදි පිළිතුරයි! ගැටළුව සම්බන්ධ වන්නේ පාවෙන සංඛ්‍යා අභ්‍යන්තරව ක්‍රියා කරන ආකාරය සමඟ මිස ජාවාස්ක්‍රිප්ට් ගැන නොවේ
ඩැනියෙල් සැන්

22
ඇත්ත වශයෙන්ම, ඔබ 100 න් ගුණ කිරීමට පෙර එප්සිලෝන් එකතු කළ Math.round( (num + Number.EPSILON) * 100) / 100යුතුය. නිවැරදිව වටකුරු කිරීම සඳහා මෙය නිවැරදි ක්‍රමය බව මම එකඟ වෙමි (එය මෙම ප්‍රශ්නයේදී අසන ලද දේම නොවේ).
maganap

2
ron ක්‍රොන්වෙල් හ්ම්. ඔයා හරි; දිශාව තෝරා කරන්නේ තේරුමක්. ඒ නිසා මම හිතන්නේ මගේ ඉතිරි විරෝධය නම් මෙය කිරීම අර්ථවත් වන්නේ ඔබ වසමක වැඩ කරන්නේ නම් ඔබේ වටිනාකම “වට අංකයක්” යැයි සිතීමට ප්‍රතිපත්තිමය හේතුවක් ඇති බවය. ඔබේ ආදානය දශමස්ථාන කුඩා සංඛ්‍යාවක් සහිත සංඛ්‍යා මත සරල ගණිතමය මෙහෙයුම්වල ප්‍රති result ලයක් බව ඔබ දන්නේ නම්, නිසැකවම, ඔබට බොහෝ විට ඇත්තේ 0.004999999999999999සංයුක්ත පාවෙන ලක්ෂ්‍ය දෝෂයේ ප්‍රති result ලයක් ලෙස පමණක් වන අතර ගණිතමය වශයෙන් නිවැරදි ප්‍රති result ලය 0.005 විය හැකිය. එය සංවේදකයකින් කියවීමක් නම්? එතරම් නොවේ.
මාර්ක් අමරි

1
chamarchaos එය අසාර්ථක නොවේ: අර්ධ සෑම විටම වටකුරු වේ . උදා Math.round(1.5)= 2, නමුත් Math.round(-1.5)= -1. එබැවින් මෙය පරිපූර්ණ ලෙස අනුකූල වේ. මෙහි -1 යනු -2 ට වඩා වැඩිය, -1000 -1000.01 ට වඩා වැඩි ය. වැඩි නිරපේක්ෂ සංඛ්‍යා සමඟ පටලවා නොගත යුතුය .
cronvel

84

කෙනෙකුට භාවිතා කළ හැකිය .toFixed(NumberOfDecimalPlaces).

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

4
එසේම එය පසුපස ශුන්‍යයන් එකතු කරන නිසා, මුල් ප්‍රශ්නය ඉල්ලූයේ එය නොවේ .
ඇලෙස්ටෙයාර් මාව්

2
නමුත් පසුපස ශුන්‍යයන් රීජෙක්ස් එකකින් පහසුවෙන් ඉවත් කළ හැකිය, එනම් `අංකය (10.10000.toFixed (2) .ප්‍රස්ථාරය (/ 0 + $ /, ''))` => 10.1
චැඩ්

1
@daniel මෙම ඉහළ පිළිතුර (දැන් වන විට) ඒ වන නමුත් එය කරන්නේ නැහැ alsways නිවැරදිව වටය, උත්සාහක +(1.005).toFixed(2)නැවත වන 1වෙනුවට 1.01.
එමිලි බර්ජරන්

3
HaChadMcElligott: ඔබේ රීජෙක්ස් පූර්ණ සංඛ්‍යා සමඟ හොඳින් ක්‍රියා නොකරයි: Number(9).toFixed(2).replace(/0+$/, '')=> "9."
ජේකබ් වැන් ලින්ගන්

මෙය වටකුරු නොවන බව පෙනේ. එය මූලික වශයෙන් කපා දමයි. සමහර අවස්ථාවලදී, ප්රමාණවත්ය! ස්තූතියි.
iedmrc

78

මෙම ප්රශ්නය සංකීර්ණයි.

අපට ශ්‍රිතයක් ඇතැයි සිතමු roundTo2DP(num), එය පාවීමක් තර්කයක් ලෙස ගෙන වටකුරු අගයක් දශමස්ථාන 2 ක් වෙත ලබා දෙයි. මෙම එක් එක් ප්‍රකාශනය ඇගයීමට ලක් කළ යුත්තේ කුමක් ද?

  • roundTo2DP(0.014999999999999999)
  • roundTo2DP(0.0150000000000000001)
  • roundTo2DP(0.015)

'පැහැදිලිව පෙනෙන' පිළිතුර නම්, පළමු උදාහරණය 0.01 දක්වා විය යුතු අතර (එය 0.02 ට වඩා 0.01 ට ආසන්න බැවින්) අනෙක් දෙක 0.02 ට වට විය යුතුය (මන්ද 0.0150000000000000001 0.01 ට වඩා 0.02 ට ආසන්න වන අතර 0.015 හරියටම අඩක් අතර ඇති නිසා ඒවා සංඛ්‍යාත්මකව ගණනය කරන ගණිතමය සම්මුතියක් ඇත).

ඔබ අනුමාන කළ අල්ලා ගැනීම නම්, එම පැහැදිලි පිළිතුරු ලබා දීම සඳහා එය ක්‍රියාත්මක roundTo2DP කළ නොහැකි වීමයි, මන්ද එයට ලබා දුන් අංක තුනම එකම සංඛ්‍යාවක් වන බැවිනි. අයිඊඊඊ 754 ද්විමය පාවෙන ලක්ෂ්‍ය සංඛ්‍යා (ජාවාස්ක්‍රිප්ට් භාවිතා කරන ආකාරයේ) බොහෝ පූර්ණ සංඛ්‍යා නොවන සංඛ්‍යා නිරූපණය කළ නොහැක, එබැවින් ඉහත සංඛ්‍යාත්මක වචනාර්ථ තුනම අසල ඇති වලංගු පාවෙන ලක්ෂ්‍ය අංකයකට රවුම් වේ. මෙම අංකය, එය සිදු වන විට, හරියටම වේ

0.01499999999999999944488848768742172978818416595458984375

එය 0.02 ට වඩා 0.01 ට ආසන්න වේ.

ඔබගේ බ්‍රව්සර් කොන්සෝලය, නෝඩ් ෂෙල් හෝ වෙනත් ජාවාස්ක්‍රිප්ට් පරිවර්තකයේදී අංක තුනම එක හා සමාන බව ඔබට දැක ගත හැකිය. ඒවා සංසන්දනය කරන්න:

> 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 වගන්තියේ ECMAScript පිරිවිතරයෙන් පිළිතුර සොයාගත හැකිය : අංක වර්ගයට අදාළ වන ToString . මෙහි යම් සංඛ්‍යාවක් m නූලක් බවට පරිවර්තනය කිරීමේ නීති රීති දක්වා ඇත. ප්‍රධාන කොටස 5 වන ලක්ෂ්‍යය වන අතර, පූර්ණ සංඛ්‍යා s ජනනය වන අතර එහි ඉලක්කම් m හි සංගීත නිරූපණය සඳහා භාවිතා වේ .

ඉඩ n , k , සහ ගේ එවැනි නිඛිල විය k ≥ 1, 10 k -1ගේ <10 k , සඳහා අංකය වටිනාකම ගේ × 10 n - k යනු මීටර් , හා k හැකි තරම් කුඩා වේ. K හි දශම නිරූපණය දී ඉලක්කම් සංඛ්යාව බව සටහන ගේ බව, ගේ 10 බෙදිය නොහැකි වන අතර, අවම ලෙස සැලකිය යුතු ඉලක්කම් බව ගේ අවශ්යයෙන්ම විශිෂ්ඨ ලෙස මෙම උපමානයන් හා තීරණය කර නැත.

මෙහි ප්‍රධාන කොටස වන්නේ " k හැකි තරම් කුඩා" අවශ්‍යතාවයයි. එම අවශ්‍යතාවයට සමාන වන්නේ අවශ්‍යතාවයක් වන අතර, අංකයක් ලබා දී ඇති විට m, එම අවශ්‍යතාවය සපුරාලන අතරම එහි අගය අවම සංඛ්‍යා සංඛ්‍යාවක්String(m) තිබිය යුතුය . අප එය දැනටමත් දන්නා බැවින් , සත්‍ය විය යුත්තේ මන්දැයි දැන් පැහැදිලි ය.Number(String(m)) === m0.015 === 0.0150000000000000001String(0.0150000000000000001) === '0.015'

ඇත්ත වශයෙන්ම, මෙම සාකච්ඡාවෙන් කිසිවක් ආපසු පැමිණිය roundTo2DP(m) යුතු දේට සෘජුවම පිළිතුරු දී නැත . නම් mගේ නිවැරදි වටිනාකම 0,01499999999999999944488848768742172978818416595458984375, නමුත් එහි සංගීත නිරූපණය '0,015' නම් කුමක් වේ නිවැරදි ගණිතමය, ප්රායෝගිකව, දාර්ශනික, හෝ ඕනෑම දෙයක් - - අපි දශම ස්ථාන දෙකක් එය අවට විට පිළිතුර?

මේ සඳහා නිවැරදි පිළිතුරක් නොමැත. එය ඔබගේ භාවිත අවස්ථාව මත රඳා පවතී. ඔබට බොහෝ විට සංගීත නිරූපණයට ගරු කිරීමට අවශ්‍ය වන අතර ඉහළට වටයන්නේ:

  • නිරූපණය වන අගය සහජයෙන්ම විවික්ත වේ, උදා: ඩිනාර් වැනි දශම 3 ක ස්ථානයක මුදල් ප්‍රමාණයකි. මේ අවස්ථාවේ දී, සැබෑ 0,015 වැනි අංකය වටිනාකම වේ 0,015, සහ 0,0149999999 ... එය ද්විමය ඉපිලුම් ලක්ෂ්ය දී ලැබෙන බව නියෝජනය වන වරදක් යයි වරදවා වටහා වේ. (ඇත්ත වශයෙන්ම, එවැනි අගයන් හැසිරවීම සඳහා ඔබ දශම පුස්තකාලයක් භාවිතා කළ යුතු බවත්, ඒවා කිසි විටෙකත් ද්විමය පාවෙන ලක්ෂ්‍ය අංක ලෙස නිරූපණය නොකරන බවත් බොහෝ දෙනා තර්ක කරනු ඇත.)
  • අගය පරිශීලකයෙකු විසින් ටයිප් කරන ලදි. මෙම අවස්ථාවේ දී, නැවතත්, ඇතුළත් කළ නිශ්චිත දශම අංකය ආසන්නතම ද්විමය පාවෙන ලක්ෂ්‍ය නිරූපණයට වඩා 'සත්‍ය' වේ.

අනෙක් අතට, ඔබේ වටිනාකම සහජයෙන්ම අඛණ්ඩ පරිමාණයකින් වන විට ද්විමය පාවෙන ලක්ෂ්‍ය අගයට ගරු කිරීමට සහ පහළට වටයන්නට ඔබට අවශ්‍ය වනු ඇත - නිදසුනක් ලෙස, එය සංවේදකයකින් කියවීමක් නම්.

මෙම ප්‍රවේශයන් දෙක සඳහා විවිධ කේත අවශ්‍ය වේ. අංකයේ සංගීත නිරූපණයට ගරු කිරීම සඳහා, අපට (තරමක් දුරට සියුම් කේතයක් සහිතව) අපගේම වටකුරු ක්‍රියාවට නැංවිය හැකිය, එය කෙලින්ම සංගීත නිරූපණය මත ක්‍රියා කරයි, ඉලක්කම් අනුව ඉලක්කම්, ඔබ පාසලේදී භාවිතා කළ ඇල්ගොරිතම භාවිතා කරමින් අංක රවුම් කරන ආකාරය උගන්වන ලදී. පහත දැක්වෙන්නේ දශමස්ථානයෙන් පසු පසුපස බිංදුව ඉවත් කිරීමෙන් “අවශ්‍ය විට පමණක්” සංඛ්‍යාව දශම ස්ථාන 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'

ඉහත කාර්යය බොහෝ විට පරිශීලකයින් තමන් ඇතුළු කර ඇති සංඛ්‍යා වැරදි ලෙස වට කර ඇති බව වළක්වා ගැනීමට භාවිතා කිරීමට අවශ්‍ය දේ විය හැකිය .

(විකල්පයක් ලෙස, ඔබට වෙනස් ආකාරයකින් ක්‍රියාත්මක කිරීම හා සමානව ක්‍රියා කරන රවුන්ඩ් 10 පුස්තකාලය උත්සාහ කළ හැකිය .)

නමුත් ඔබට දෙවන වර්ගයේ අංකයක් තිබේ නම් - අඛණ්ඩ පරිමාණයකින් ගත් අගයක්, අඩු දශම ස්ථාන සහිත දළ වශයෙන් දශම නිරූපණයන් වැඩි සංඛ්‍යාවක් ඇති අයට වඩා නිවැරදි යැයි සිතීමට හේතුවක් නොමැති නම් කුමක් කළ යුතුද? එවැනි අවස්ථාවකදී, අපට නූල් නිරූපණයට ගරු කිරීමට අවශ්‍ය නැත , මන්ද එම නිරූපණය (පිරිවිතරයේ විස්තර කර ඇති පරිදි) දැනටමත් වටකුරු ය; "0.014999999 ... 0.015 දක්වා වට 375 ක් වන අතර එය 0.02 දක්වා වටය, එබැවින් 0.014999999 ... 375 වට 0.02 දක්වා" යැයි පැවසීමේ වැරැද්ද කිරීමට අපට අවශ්‍ය නැත.

මෙහිදී අපට සරලවම ගොඩනංවන toFixedක්‍රමය භාවිතා කළ හැකිය . Number()ආපසු එවූ toFixedනූල් ඇමතීමෙන් අපට ලැබෙන්නේ ශුන්‍ය අගයක් නොමැති අංකයක් ලැබෙන බවයි (මෙම පිළිතුරෙහි මුලින් සාකච්ඡා කළ අංකයක නූල් නිරූපණය ජාවාස්ක්‍රිප්ට් ගණනය කරන ආකාරයට ස්තූතියි).

/**
 * 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);
}

සමහර අවස්ථා වලදී මෙය ක්‍රියා නොකරයි: උත්සාහ කරන්න ( jsfiddle ) සමඟ roundStringNumberWithoutTrailingZeroes(362.42499999999995, 2). අපේක්ෂිත ප්‍රති result ලය (PHP හි මෙන් echo round(362.42499999999995, 2)) : 362.43. සත්‍ය 362.42
ප්‍රති result ලය

1
@ ආචාර්ය ගියන්ලූගිසැන්සැනෙටිනි හුහ්. අමුතුයි. PHP විසින් round362.43 ලබා දෙන්නේ මන්දැයි මට විශ්වාස නැත . 362.42499999999995 362.425 ට වඩා අඩු බැවින් එය ගණිතමය වශයෙන් වැරදියි (ගණිතයේ සහ කේතයේ - 362.42499999999995 < 362.425JS සහ PHP යන දෙඅංශයෙන්ම සත්‍ය වේ). PHP හි පිළිතුර මුල් හා වටකුරු පාවෙන ලක්ෂ්‍ය අංක අතර දුර අවම නොකරයි 362.43 - 362.42499999999995 > 362.42499999999995 - 362.42. Php.net/manual/en/function.round.php ට අනුව , PHP හි roundC99 ප්‍රමිතිය අනුගමනය කරයි; සිදුවන්නේ කුමක්ද යන්න තේරුම් ගැනීමට මට සී දේශයට යා යුතුය.
මාර්ක් අමරි

1
පීඑච්පී ප්‍රභවයේ වටකුරු ක්‍රියාවට නැංවීම පිළිබඳව සොයා බැලීමෙන් පසුව , එය කරන්නේ කුමක් දැයි මට කිසිදු හෝඩුවාවක් නැත. එය සාර්ව හා අතු වලින් පිරී ඇති බිහිසුණු සංකීර්ණ ක්‍රියාවට නැංවීමකි. "PHP හි පිළිතුර අමු අමුවේ වැරදියි, අපි දෝෂ වාර්තාවක් ගොනු කළ යුතුයි" යන්නෙන් ඔබ්බට කුමක් කිව යුතුදැයි මට විශ්වාස නැත. මාර්ගය වන විට ඔබ 362.42499999999995 අංකය සොයාගත්තේ කෙසේද?
මාර්ක් අමරි

1
@ Dr.GianluigiZaneZanettini මම දෝෂ වාර්තාවක් නිර්මාණය කර ඇත්තෙමි: bugs.php.net/bug.php?id=75644
මාර්ක්

2
@ Dr.GianluigiZaneZanettini "මට තේරුමක් තිබේද?" - නොමැත; වටකුරු වැඩ කරන්නේ එසේ නොවේ. 1.000005 පහකින් අවසන් වේ, නමුත් ආසන්නතම නිඛිලයට වටකුරු නම් පිළිතුර 1 විය යුතුය. 2 නොවේ. වටකුරු දිශාව තීරණය කළ යුත්තේ තුන්වන දශම ස්ථානය වන 4 වන
වටයයි

77

සලකා බලන්න .toFixed()සහ .toPrecision():

http://www.javascriptkit.com/javatutor/formatnumber.shtml


1
toFixed කුමක් වුවත් සෑම අගයකටම දශම ලකුණු එකතු කරයි.
stinkycheeseman

13
දෙකම මෙහි
නිෂ් less ල ය

අවාසනාවකට මෙන්, මෙම කාර්යයන් දෙකම අතිරේක දශම ස්ථාන එකතු කරනු ඇත @stinkycheeseman ට අවශ්‍ය නොවන බව පෙනේ.
ජැක්වන්ඩර්ස්


2
ඒවා සංඛ්‍යා නොව සංඛ්‍යා නූල්
යවයි

63

නිවැරදි වටකුරු ක්‍රමයක්. මුලාශ්‍රය: මොසිල්ලා

(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

කවුරුහරි මෙය GitHub සහ npm මත ද තබයි
ජෝ ලිස්

හපොයි Math.round10(3544.5249, -2)ඒ වෙනුවට ප්රතිලාභ 3544,52 3544,53
Matija

2
Ati මතිජා වුල්ෆ්රාම් ඇල්ෆා 3544.52 ද පවසයි. වත්මන් අංකය සහ වටකුරු ආසන්න කිරීම අතර ඇති දෝෂය අවම කිරීමට ඔබට අවශ්‍යය. 3544.5249දශම ස්ථාන 2 කට ආසන්නතම ආසන්න අගය 3544.52(දෝෂය = 0.0049). එය එසේ නම් 3544.53, දෝෂය 0.0051 වනු ඇත. ඔබ කරන්නේ අනුක්‍රමික වටරවුමයි. එනම් Math.round10 (Math.round10 (3544.5249, -3), -2) එය විශාල වටකුරු දෝෂයක් ලබා දෙන අතර එබැවින් යෝග්‍ය නොවේ.
පරිශීලක

3
Ati මාතිජා, ගණිතමය දෘෂ්ටි කෝණයෙන් බැලූ විට 3544.5249 වටකුරු 3544.52 මිස 3544.53 නොවේ, එබැවින් මෙම කේතය නිවැරදි ය. ඔබට එය 3544.53 දක්වා වට කිරීමට අවශ්‍ය නම් සහ මෙවැනි අවස්ථා (දැඩි වුවද වැරදියි), මේ වගේ දෙයක් කරන්න:number += 0.00011
බොසිඩාර් සිකාන්ජික්

Ati මතිජා: මම හිතන්නේ ශ්‍රිතය ක්‍රියාත්මක විය යුතුයි. සමහර විට ඔබට Math.round10( Math.round10(3544.5249, -3) , -2)
වටය නැවත කියවීමට

60

මෙහි හමු වූ පිළිතුරු කිසිවක් නිවැරදි නොවේ . inkstinkycheeseman වටකර ගැනීමට ඉල්ලා සිටියේය , ඔබ සියලු සංඛ්යාව තේරී පත්විණි.

වට කර ගැනීමට, මෙය භාවිතා කරන්න:

Math.ceil(num * 100)/100;

15
උදාහරණ ආදානය සහ ප්‍රතිදානය පෙන්නුම් කරන්නේ ප්‍රශ්නය 'වටයන්න ...' යැයි පැවසුවද එය සැබවින්ම අදහස් කළේ 'වටේ සිට ...' යන්නයි.
ජේඩීඑම්

2
inkstinkycheeseman නිශ්චිත අවස්ථාවක දෝෂයක් පෙන්වා දෙමින් සිටියේය, ඔහුට සෑම විටම සිවිලිම මෙන් වට කර ගැනීමට අවශ්‍ය නොවීය, ඔහුට අවශ්‍ය වූයේ 0.005 දක්වා 0.01 දක්වා වට කිරීමටයි
mjaggard

9
පරීක්ෂා අතර අමුතු දෝෂයක් සොයා Math.ceil(1.1 * 100)/100;-it ප්රතිලාභ 1.11නිසා 1.1 * 100 අතර, 110.00000000000001නවතම නවීන බ්රවුසරයන් ෆයර්ෆොක්ස්, ක්රෝම්, Safari සහ ඔපෙරා අනුව ... IE, පැරණි විලාසිතා, තවමත් සිතන 1.1*100=1100.
skobaljic

1
oskobaljic tryMath.ceil(num.toFixed(4) * 100) / 100
treeface

1
ree ට්‍රීෆේස් ෆයර්ෆොක්ස් හි Math.ceil((1.1).toFixed(4) * 100) / 100ද නැවත පැමිණෙනු 1.11ඇත, නවීන බ්‍රව්සර් ගැටළුව / දෝෂය ගුණ කිරීම සමඟ වන අතර මිනිසුන් ඒ ගැන දැන සිටිය යුතුය (උදාහරණයක් ලෙස මම ලොතරැයි ක්‍රීඩාවක යෙදී සිටියෙමි).
skobaljic

48

එය කිරීමට සරල ක්‍රමයක් මෙන්න:

Math.round(value * 100) / 100

ඔබට ඉදිරියට ගොස් වෙනම කාර්යයක් කිරීමට අවශ්‍ය වුවද එය ඔබ වෙනුවෙන් කළ හැකිය:

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

එවිට ඔබ හුදෙක් වටිනාකමින් සමත් වනු ඇත.

දෙවන පරාමිතියක් එකතු කිරීමෙන් ඔබට එය ඕනෑම අත්තනෝමතික දශම සංඛ්‍යාවක් දක්වා වැඩි කළ හැකිය.

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

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

2
මෙම විසඳුම වැරදියි, stackoverflow.com/questions/38322372/… බලන්න ඔබ 156893.145 ආදානය කර ඉහත ශ්‍රිතය සමඟ එය වට කළහොත් ඔබට 156893.15 වෙනුවට 156893.14 ලැබේ !!!
saimiris_devel

2
aisaimiris_devel, ජාවාස්ක්‍රිප්ට් හි සංඛ්‍යාත්මක සංඛ්‍යාත්මක නිරූපණය අසමත් වන අවස්ථාවක් සොයා ගැනීමට ඔබට හැකි විය. එය වැරදි ලෙස වට වන බව ඔබ නිවැරදිය. නමුත් - එයට හේතුව 100 න් ගුණ කළ විට ඔබගේ නියැදි අංකය දැනටමත් කැඩී ඇති බැවිනි (15689314.499999998). සැබවින්ම, අංග සම්පූර්ණ පිළිතුරකට ජාවාස්ක්‍රිප්ට් තාත්වික සංඛ්‍යා හැසිරවීමේ නොගැලපීම් සැලකිල්ලට ගැනීම සඳහා විශේෂයෙන් සංවර්ධනය කරන ලද පුස්තකාලයක් අවශ්‍ය වේ. එසේ නොමැතිනම්, මෙම ප්‍රශ්නයට ලබා දී ඇති පිළිතුරු කිසිවක් අවලංගු කිරීමට ඔබට හැකිය.
ජේඩීඑම්

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

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

1
ඔබ ඔබේ අංකයේ සංගීත නිරූපණය ගෙන එය වට කළහොත් මෙය ඔබට ලැබෙන ප්‍රති results ලම ලබා නොදේ. උදාහරණයක් ලෙස , +(0.015).toFixed(2) == 0.01.
මාර්ක් අමරි

35

මට නම් Math.round () නිවැරදි පිළිතුරක් ලබා දුන්නේ නැත. ෆික්ස්ඩ් (2) වඩා හොඳින් ක්‍රියා කරන බව මට පෙනී ගියේය . දෙකෙහිම උදාහරණ පහත දැක්වේ:

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

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


ToFixed විසින් වටකුරු කිරීමක් සිදු නොකරන බවත්, Math.round ආසන්නතම මුළු අංකයටම වට වන බවත් සැලකිල්ලට ගැනීම වැදගත්ය. එබැවින් දශමයන් ආරක්ෂා කර ගැනීම සඳහා අපි මුල් සංඛ්‍යාව දහයේ බල ගණනින් ගුණ කළ යුතු අතර, ඔබ අපේක්ෂිත දශම ගණන නියෝජනය කරන ශුන්‍යයන්, ඉන්පසු ප්‍රති result ලය එකම සංඛ්‍යාවෙන් බෙදන්න. ඔබගේ නඩුවේදී: Math.round (43000/80000 * 100 * 100) / 100. ප්‍රති to ලයේ සෑම විටම දශම දෙකක් ඇති බව සහතික කිරීම සඳහා අවසාන වශයෙන් ස්ථාවර (2) යෙදිය හැකිය (අවශ්‍ය අවස්ථාවන්හිදී ශුන්‍යයන් පසුපසින්) - පරිපූර්ණයි සිරස් අතට ඉදිරිපත් කරන ලද සංඛ්‍යා මාලාවක් දකුණු-පෙළගැස්වීම සඳහා :)
ටර්බෝ

7
.TOFIxed () මඟින් නිමැවුමක් නිකුත් කරයි, අංකයක් නොවේ.
carpiediem

2
මෙය තවමත් වටය විසඳන්නේ නැත 1.005. (1.005).toFixed(2)තවමත් ප්‍රති results ල 1.00.
DPac

34

මෙම ශ්‍රිතය භාවිතා කරන්න Number(x).toFixed(2);


8
සියලු එය ආවරණය කරනවා Numberනැවත, ඔබ කැමති නැහැ ඒ වැලක් ලෙස ආපසු නම්:Number(Number(x).toFixed(2));

5
මෙම Numberඇමතුම් නැහැ, අවශ්ය වන්නේ x.toFixed(2)වැඩ.
bgusach

3
x.toFixed (2) ප්‍රකාශය ආපසු එන නූලක් මිස අංකයක් නොවන බැවින් gbgusach අංක ඇමතුම අවශ්‍ය වේ. නැවත අංකයට පරිවර්තනය කිරීම සඳහා අප අංකය
මොහාන් රාම්

2
මෙම ක්‍රමය භාවිතා කරන විට (1).toFixed(2)නැවත පැමිණේ 1.00, නමුත් 1මෙම අවස්ථාවේ දී ප්‍රශ්න කරන්නා අවශ්‍ය වේ.
ඉයුජින් මාලා

1
මෙය ක්‍රියා නොකරයි, එය විය යුතු විට 1.005.toFixed(2)අස්වැන්න "1"ලැබේ "1.01".
ඇඩම් ජාගෝස්

33

2017
ස්වදේශීය කේතය භාවිතා කරන්න.toFixed()

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

ඔබට දැඩි වීමට අවශ්‍ය නම් සහ අවශ්‍ය නම් ඉලක්කම් එකතු කරන්න replace

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

3
ToFixed ක්‍රමය මඟින් නූලක් ලබා දෙයි. ඔබට සංඛ්‍යා ප්‍රති result ලයක් අවශ්‍ය නම් toFixed හි ප්‍රති result ලය parseFloat වෙත යැවිය යුතුය.
සැම්බොනිලි

Amb සැම්බොනිලි හෝ අවශ්‍ය නම් 1 න් ගුණ කරන්න. නමුත් ස්ථාවර සංඛ්‍යාවක් නිසා බොහෝ අවස්ථාවන් ප්‍රදර්ශනය සඳහා වන අතර ගණනය කිරීමේ
නූල

2
-1; toFixedඔබට පිළිතුරු දීමට වසර ගණනාවකට පෙර පිළිතුරු කිහිපයකින් යෝජනා කර ඇතිවා පමණක් නොව , ප්‍රශ්නයේ “අවශ්‍ය නම් පමණක්” කොන්දේසිය තෘප්තිමත් කිරීමට එය අසමත් වේ; අසන්නාට අවශ්‍ය තැන (1).toFixed(2)ලබා දෙයි ."1.00""1"
මාක් එමරි

හරි තේරුණා. මම ඒ සඳහා යම් විසඳුමක් එකතු කරමි
pery mimon

ඔබ ලොඩාෂ් භාවිතා කරන්නේ නම්, එය ඊටත් වඩා පහසු ය: _.round (number, decimalPlace) මගේ අවසාන අදහස මකා දැමුවා, cuz එයට ගැටලුවක් තිබේ. ලොඩාෂ් _.රවුන්ඩ් වැඩ කරයි. 1.005 දශම ස්ථානය 2 ක් සමඟ 1.01 බවට පරිවර්තනය වේ.
ඩෙවින් ෆීල්ඩ්ස්

32

මෙම සැහැල්ලු බර විසඳුම උත්සාහ කරන්න :

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

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

මේ හා අතර වෙනසක් තිබේදැයි ඕනෑම අයෙක් දන්නවාද return Number(x.toFixed(digits))?

1
@ ජෝරොක් ... කෙසේ හෝ .toFixed()සංඛ්‍යා සඳහා පමණක් ඉඩ දෙන බැවින් මට පෙනෙන පරිදි කිසිදු වෙනසක් නොකළ යුතුය .
petermeissner

4
මෙම පිටුවේ කිහිප වතාවක් සඳහන් කර ඇති ආකාරයටම මෙම පිළිතුරට සමාන ගැටලුවක් ඇත. ඒ වෙනුවට ප්‍රති round(1.005, 2)result ලයක් උත්සාහ කර බලන්න . 11.01
මිල්කොන්ඩොයින්

වටකුරු ඇල්ගෝගේ ගැටලුවක් ලෙස පෙනේද? - සිතීමට වඩා වැඩි ගණනක් ඇත: en.wikipedia.org/wiki/Rounding ... round(0.995, 2) => 0.99; round(1.006, 2) => 1.01; round(1.005, 2) => 1
petermeissner

31

ඒ සඳහා ක්‍රම කිහිපයක් තිබේ. මා වැනි අය සඳහා, ලොඩාෂ්ගේ ප්‍රභේදය

function round(number, precision) {
    var pair = (number + 'e').split('e')
    var value = Math.round(pair[0] + 'e' + (+pair[1] + precision))
    pair = (value + 'e').split('e')
    return +(pair[0] + 'e' + (+pair[1] - precision))
}

භාවිතය:

round(0.015, 2) // 0.02
round(1.005, 2) // 1.01

ඔබේ ව්‍යාපෘතිය jQuery හෝ ලොඩාෂ් භාවිතා කරන්නේ නම්, ඔබට roundපුස්තකාලවල නිසි ක්‍රමයක් සොයාගත හැකිය .

යාවත්කාලීන කිරීම 1

මම ප්‍රභේදය ඉවත් කළෙමි n.toFixed(2), එය නිවැරදි නොවන නිසා. ස්තූතියි @ avalanche1


දෙවන විකල්පය හරියටම දශම ලකුණු දෙකක් සහිත නූලක් ලබා දෙනු ඇත. ප්‍රශ්නය දශම ලකුණු ඉල්ලන්නේ අවශ්‍ය නම් පමණි. මෙම අවස්ථාවේ දී පළමු විකල්පය වඩා හොඳය.
මාකෝස් ලීමා

Ar මාකෝස්ලීමා Number.toFixed()විසින් නූලක් ආපසු ලබා දෙන නමුත් ඊට පෙර ප්ලස් සංකේතයක් සහිතව, JS පරිවර්තකය විසින් නූල අංකයක් බවට පරිවර්තනය කරයි. මෙය සින්ටැක්ස් සීනි වේ.
stanleyxu2005

ෆයර්ෆොක්ස් හි alert((+1234).toFixed(2))"1234.00" පෙන්වයි.
මාකෝස් ලීමා

ෆයර්ෆොක්ස් මත, alert(+1234.toFixed(2))විසි කරයි SyntaxError: identifier starts immediately after numeric literal. මම 1 වන විකල්පය සමඟ බැඳී සිටිමි.
මාකෝස් ලීමා

සමහර අවස්ථා වලදී මෙය ක්‍රියා නොකරයි: උත්සාහ කරන්න ( jsfiddle ) සමඟ 362.42499999999995. අපේක්ෂිත ප්‍රති result ලය (PHP හි මෙන් echo round(362.42499999999995, 2)) : 362.43. සත්‍ය 362.42
ප්‍රති result ලය

26

ඔබ ලොඩාෂ් පුස්තකාලය භාවිතා කරන්නේ නම්, ඔබට පහත දැක්වෙන ආකාරයට ලොඩාෂ් වටකුරු ක්‍රමය භාවිතා කළ හැකිය.

_.round(number, precision)

උදා:

_.round(1.7777777, 2) = 1.78

EtPeter සම්මත ජාවාස්ක්‍රිප්ට් හා සසඳන විට ලොඩාෂ් සපයන ක්‍රියාකාරීත්ව කට්ටලය ඇත්තෙන්ම හොඳයි. කෙසේ වෙතත්, සම්මත ජේඑස් හා සසඳන විට ලෝඩාෂ්ට යම් කාර්ය සාධන ගැටලුවක් ඇති බව මම අසා ඇත්තෙමි. codeburst.io/…
මධුර ප්‍රදීප්

1
ලොඩාෂ් භාවිතා කිරීම සමඟ කාර්ය සාධන අඩුපාඩු ඇති බව මම පිළිගනිමි. මම හිතන්නේ එම ගැටළු බොහෝ වියුක්තයන්ට පොදු ය. නමුත් මෙම ත්‍රෙඩ් එකේ පිළිතුරු කීයක් තිබේද යන්න සහ අද්භූත අවස්ථා සඳහා බුද්ධිමය විසඳුම් අසමත් වන්නේ කෙසේදැයි බලන්න. මෙම රටාව jQuery සමඟ අප දැක ඇති අතර අපගේ බොහෝ භාවිත අවස්ථා විසඳන බ්‍රව්සර් පොදු ප්‍රමිතියක් අනුගමනය කළ විට මූල ගැටළුව විසඳුණි. කාර්ය සාධන බාධක පසුව බ්‍රව්සර් එන්ජින් වෙත ගෙන යන ලදී. මම හිතන්නේ ලොඩාෂ් වලටත් එයම සිදුවිය යුතුයි. :)
පීටර්

26

ES6 සිට toPrecision භාවිතා කරමින් මෙය කිරීමට 'නිසි' ක්‍රමයක් ඇත (සංඛ්‍යාලේඛන ඉක්මවා නොයෑම සහ වැඩමුළු නිර්මාණය නොකර)

var x = 1.49999999999;
console.log(x.toPrecision(4));
console.log(x.toPrecision(3));
console.log(x.toPrecision(2));

var y = Math.PI;
console.log(y.toPrecision(6));
console.log(y.toPrecision(5));
console.log(y.toPrecision(4));

var z = 222.987654
console.log(z.toPrecision(6));
console.log(z.toPrecision(5));
console.log(z.toPrecision(4));

එවිට ඔබට සාධාරණ විය හැකි parseFloatඅතර ශුන්‍යයන් 'පහව යනු ඇත'.

console.log(parseFloat((1.4999).toPrecision(3)));
console.log(parseFloat((1.005).toPrecision(3)));
console.log(parseFloat((1.0051).toPrecision(3)));

එය '1.005 වටකුරු ගැටළුව' විසඳන්නේ නැත - එය පාවෙන භාග සැකසෙන්නේ කෙසේද යන්නට ආවේනික බැවින් .

console.log(1.005 - 0.005);

ඔබ පුස්තකාල සඳහා විවෘත නම් ඔබට bignumber.js භාවිතා කළ හැකිය

console.log(1.005 - 0.005);
console.log(new BigNumber(1.005).minus(0.005));

console.log(new BigNumber(1.005).round(4));
console.log(new BigNumber(1.005).round(3));
console.log(new BigNumber(1.005).round(2));
console.log(new BigNumber(1.005).round(1));
<script src="https://cdnjs.cloudflare.com/ajax/libs/bignumber.js/2.3.0/bignumber.min.js"></script>


3
(1.005).toPrecision(3)ඇත්ත වශයෙන්ම 1.00වෙනුවට නැවත පැමිණේ 1.01.
ජියාකොමෝ

toPrecisionඅපේක්ෂිත ප්‍රතිදාන වර්ගය වෙනස් කරන නූලක් ලබා දෙයි.
adamduren

Ia ජියාකොමෝ එය ක්‍රමයේ අඩුපාඩුවක් නොවේ .toPrecision, එය පාවෙන ලක්ෂ්‍ය සංඛ්‍යා වල නිශ්චිතතාවයකි (JS හි ඇති සංඛ්‍යා) - උත්සාහ කරන්න 1.005 - 0.005, එය නැවත පැමිණේ 0.9999999999999999.
ෂවු-කෝට්

1
(1).toPrecision(3)'1.00' ආපසු එවයි, නමුත් ප්‍රශ්න කරන්නාට 1මෙම නඩුවේ සිටීමට අවශ්‍ය විය .
ඉයුජින් මාලා

1
@ ජියාකොමෝ පැවසූ පරිදි, මෙම පිළිතුර “සැලකිය යුතු ඉලක්කම්” “දශම ස්ථාන ගණනාවකට වට කිරීම” සමඟ පටලවා ඇති බව පෙනේ. toPrecisionආකෘතිය අදාළද, දෙවැන්න නොවේ, සහ OP ගේ ප්‍රශ්නයට පිළිතුරක් නොවේ, එය මුලින් අදාළ යැයි පෙනෙන්නට තිබුණද, එය බොහෝ වැරදිසහගත වේ. En.wikipedia.org/wiki/Significant_figures බලන්න . උදාහරණයක් ලෙස Number(123.4).toPrecision(2)ප්‍රතිලාභ "1.2e+2"සහ Number(12.345).toPrecision(2)ප්‍රතිලාභ "12". @ ඇඩම්ඩුරෙන්ගේ අදහස සමඟ මම එකඟ වෙමි, එය නුසුදුසු නූලක් ආපසු ලබා දෙයි (විශාල ගැටළුවක් නොව සුදුසු නොවේ).
නීක්

23

මාර්ක් ජී සහ ලැවමන්ටිස් පිළිගත් විසඳුමට වඩා හොඳ විසඳුමක් ඉදිරිපත් කළහ. ඔවුන් වැඩි වැඩියෙන් ලබා නොගැනීම ලැජ්ජාවකි!

එම්ඩීඑන් මත පදනම් වූ පාවෙන ලක්ෂ්‍ය දශම ගැටළු විසඳීමට මා භාවිතා කරන කාර්යය මෙන්න . එය ලැවමන්ටිස්ගේ විසඳුමට වඩා ජනක (නමුත් සංක්ෂිප්ත අඩු) ය:

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

ලැවමන්ටිස්ගේ විසඳුමට සාපේක්ෂව අපට කළ හැකිය ...

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

2
ඔබේ විසඳුම MDN හි විසඳුමට පටහැනිව සමහර අවස්ථා ආවරණය නොකරයි. එය කෙටි විය හැකි නමුත් එය නිවැරදි නොවේ ...
astorije

1
වටය (-1835.665,2) => -1835.66
ජෝර්ජ් සම්පත්යෝ

22

මෙය ඔබට උදව් විය හැකිය:

var result = Math.round(input*100)/100;

වැඩි විස්තර සඳහා, ඔබට මෙම සබැඳිය බැලීමට හැකිය

Math.round (num) vs num.toFixed (0) සහ බ්‍රව්සරයේ නොගැලපීම්


1
ප්‍රායෝගිකව එකම දේ වන බැවින් පිළිගත් පිළිතුරට මෙයට වඩා වැඩි ඡන්ද ප්‍රමාණයක් ඇත්තේ ඇයි, නමුත් පිළිගත් පිළිතුරට මිනිත්තු 1 කට පසුව මෙය පළ කරන ලදි?
උපුටා ගැනීම ඩේව්

18

පහසුම ප්‍රවේශය වනුයේ toFixed භාවිතා කර අංක ශ්‍රිතය භාවිතයෙන් පසුපස ශුන්‍ය ඉවත් කිරීමයි:

const number = 15.5;
Number(number.toFixed(2)); // 15.5
const number = 1.7777777;
Number(number.toFixed(2)); // 1.78

මෙය සියලු අවස්ථාවන් සඳහා ක්‍රියා නොකරයි. පිළිතුරු පළ කිරීමට පෙර පුළුල් පරීක්ෂණ කරන්න.
බබුරාඕ

abbaburao කරුණාකර ඉහත විසඳුම ක්‍රියාත්මක නොවන අවස්ථාවක් පළ කරන්න
මාකින් වනගෝ

const number = 15; අංකය (number.toFixed (2)); 15 වෙනුවට //15.00
කෙවින් ජැංගියානි

1
E කෙවින් ජැංගියානි const number = 15; අංකය (number.toFixed (2)); // 15 - මම එය නවතම ක්‍රෝම් සහ ෆයර්ෆොක්ස් යන දෙකින්ම අත්හදා බැලුවෙමි
මාසින් වනගෝ

E කෙවින් ජැංගියානි ඔබට ලැබෙන්නේ 15.00කෙසේද? JS හි ඇති සංඛ්‍යා දශම ස්ථාන ගබඩා නොකරන අතර ඕනෑම සංදර්ශකයක් ස්වයංක්‍රීයව අතිරික්ත දශම ස්ථාන කපා දමයි (අවසානයේ ඇති ඕනෑම ශුන්‍යයන්).
VLAZ

16
var roundUpto = function(number, upto){
    return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);

toFixed(2) මෙහි 2 යනු අපට මෙම අංකය වට කිරීමට අවශ්‍ය ඉලක්කම් ගණනකි.


මෙය .toFixed () ක්‍රියාත්මක කිරීමට වඩා සරල ය. එක් වරක් එය හරහා යන්න.
රිටේෂ් ධුරි


14

පහසුම ක්‍රමය:

+num.toFixed(2)

එය එය නූලක් බවට පරිවර්තනය කර නැවත පූර්ණ සංඛ්‍යාවක් / පාවීමක් බවට පරිවර්තනය කරයි.


මෙම සරලම පිළිතුරට ස්තූතියි. කෙසේ වෙතත්, + + හි '+' යනු කුමක්ද? දශම අගය අගයෙන් පැමිණි තැනට එය මට වැඩ කළේ නැත. මම කළා: (අංක * 1) .අන්තර්ගත (2).
ඊතන්

om මෝමෝ තර්කය toFixed()3 ට වෙනස් කරන්න. එබැවින් එය එසේ වනු ඇත +num.toFixed(3). එය සිතන ආකාරයට ක්‍රියා කරයි, 1.005 වටකුරු 1.00 දක්වා වන අතර එය 1 ට සමාන වේ
බිග්පොටැටෝ

1
D එඩ්මන්ඩ් එය ආපසු එවිය යුත්තේ 1.01 මිස 1.00 නොවේ
මි.මී.

13

මෙන්න මූලාකෘති ක්රමයක්:

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

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

13

මේ වගේ දෙයක් භාවිතා කරන්න "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

1
සාවද්‍යතාවය පාවෙන නිරූපණයට ආවේනික නම් නොවේ. ඔබ එය ඉවත් කර නැවත එම පාවීම නැවත පාවීමට පරිවර්තනය කිරීමෙන් නැවත හඳුන්වා දෙනු ඇත!
බෙන් මැකින්ටයර්

13

සත්‍ය නිරවද්‍ය දශම වටකුරු නිරවද්‍යතාවය සාක්ෂාත් කර ගැනීම සඳහා හැකි සෑම ආකාරයකින්ම පුනරාවර්තනය කිරීමෙන් පසු, වඩාත් නිවැරදි හා කාර්යක්ෂම විසඳුම වන්නේ අංකය භාවිතා කිරීමයි. එප්සිලෝන්. මෙය පාවෙන ලක්ෂ්‍ය ගණිත නිරවද්‍යතාවයේ ගැටලුවට සත්‍ය ගණිතමය විසඳුමක් සපයයි. මෙහි පෙන්වා ඇති පරිදි එය පහසුවෙන් බහුකාර්ය කළ හැකිය: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON අවසන් වරට ඉතිරිව ඇති සියලුම IE පරිශීලකයින්ට සහය දැක්වීම සඳහා (පසුව සමහර විට අපි එය කිරීම නතර කළ යුතුය).

මෙහි දක්වා ඇති විසඳුමෙන් අනුවර්තනය කරන ලද්දේ: https://stackoverflow.com/a/48850944/6910392

සම්පූර්ණ පුස්තකාලයක් එකතු නොකර විකල්ප නිරවද්‍ය විචල්‍යයක් සහිත නිවැරදි දශම වටකුරු, බිම් මහල සහ සිවිලිම සපයන සරල විසඳුමක්.

යාවත්කාලීන කිරීම: අදහස් දැක්වීමේදී සර්ජි සඳහන් කළ පරිදි, පෙන්වා දීමට වටින මෙම (හෝ ඕනෑම) ක්‍රමයකට සීමාවක් තිබේ. 0.014999999999999999 වැනි සංඛ්‍යා සම්බන්ධයෙන් ගත් කල, පාවෙන ලක්ෂ්‍ය අගය ගබඩා කිරීම සඳහා නිරවද්‍යතා සීමාවන්හි නිරපේක්ෂ අද්දරට පහර දීමේ ප්‍රති result ලයක් වන සාවද්‍යතාවයන් ඔබට තවමත් අත්විඳිය හැකිය. ඒ සඳහා ගණනය කළ හැකි ගණිතයක් හෝ වෙනත් විසඳුමක් නොමැත, මන්ද එම අගය වහාම 0.015 ලෙස තක්සේරු කරනු ලැබේ. කොන්සෝලය තුළ එම අගය තනිවම යෙදීමෙන් ඔබට මෙය සනාථ කළ හැකිය. මෙම සීමාව නිසා, මෙම අගය අඩු කිරීම සඳහා නූල් හැසිරවීම භාවිතා කිරීමට පවා නොහැකි වනු ඇත, මන්ද එහි නූල් නිරූපණය හුදෙක් "0.015" වේ. ස්ක්‍රිප්ට් එකක වටිනාකම පිළිගැනීමට පෙර මේ සඳහා වන ඕනෑම විසඳුමක් දත්ත ප්‍රභවයේ තාර්කිකව යෙදිය යුතුය.

var DecimalPrecision = (function(){
        if (Number.EPSILON === undefined) {
            Number.EPSILON = Math.pow(2, -52);
        }
        this.round = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.round((n + r) * o) / o;
        }
        this.ceil = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.ceil((n + r) * o) / o;
        }
        this.floor = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.floor((n + r) * o) / o;
        }
        return this;
    })();
    console.log(DecimalPrecision.round(1.005));
    console.log(DecimalPrecision.ceil(1.005));
    console.log(DecimalPrecision.floor(1.005));
    console.log(DecimalPrecision.round(1.0049999));
    console.log(DecimalPrecision.ceil(1.0049999));
    console.log(DecimalPrecision.floor(1.0049999));
    console.log(DecimalPrecision.round(2.175495134384,7));
    console.log(DecimalPrecision.round(2.1753543549,8));
    console.log(DecimalPrecision.round(2.1755465135353,4));


1
(DecimalPrecision.round (0.014999999999999999, 2)) // ප්‍රතිලාභ 0.02
සර්ජි

හොඳ ඇල්ලීමක්! ගැටළුව වන්නේ ජේඑස් හි පාවෙන ස්ථාන ගබඩා කිරීම, සෑම විටම යම් යම් අවස්ථා තිබේ. ශුභාරංචිය නම්, ඔබ අංකයට අදාළ ගණිතයයි. එප්සිලෝන් පළමුව එම දාරයේ සිද්ධි තව දුරටත් පිටතට තල්ලු කිරීම සඳහා වඩාත් හොඳින් සුසර කළ හැකිය. එජ් නඩු සඳහා කිසිදු හැකියාවක් නොමැති බවට ඔබට සහතික වීමට අවශ්‍ය නම් ඔබේ එකම සැබෑ විසඳුම වනුයේ නූල් හැසිරවීම සහ ගණිතයයි. ඔබ අගය මත කිසියම් ගණිතමය ගණනය කිරීමක් සිදු කළ මොහොතේ (දශම චලනය කිරීමට උත්සාහ කිරීමේදී පවා), ඔබ දැනටමත් දෝෂය නිපදවා ඇත.
කේෆිෂ්

ඇත්ත වශයෙන්ම, වැඩිදුර පරීක්‍ෂා කිරීමේදී, මෙය සම්බන්ධ ගණිතයක් නිසා නොවේ, නමුත් නිශ්චිත අගය යෙදීමෙන් වහාම ගැටළුව විදහා දක්වයි. එම අංකය කොන්සෝලය තුළට ටයිප් කිරීමෙන් ඔබට මෙය තහවුරු කළ හැකි අතර එය වහාම 0.015 දක්වා තක්සේරු කරන බව බලන්න. එබැවින්, මෙය JS හි ඕනෑම පාවෙන ලක්ෂ්‍ය සංඛ්‍යාවක් සඳහා නිරවද්‍යතාවයේ නිරපේක්ෂ මායිම නියෝජනය කරයි. මෙම අවස්ථාවෙහිදී ඔබට නූල් බවට පරිවර්තනය කර හැසිරවීමට පවා නොහැකි බැවින් නූල් අගය "0.015" වනු ඇත
KFish

12

අවශ්‍ය නම් පමණක් එවැනි වටයක් ලබා ගත හැකි එක් ක්‍රමයක් නම් Number.prototype.toLocaleString () භාවිතා කිරීමයි :

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

මෙය ඔබ අපේක්ෂා කරන ප්‍රතිදානය හරියටම ලබා දෙනු ඇත, නමුත් නූල් ලෙස. ඔබ අපේක්ෂා කරන දත්ත වර්ගය නොවේ නම් ඔබට ඒවා නැවත අංක බවට පරිවර්තනය කළ හැකිය.


මෙතෙක් පැවති පිරිසිදුම විසඳුම මෙය වන අතර සියලු සංකීර්ණ පාවෙන ලක්ෂ්‍ය ගැටලු මඟහරවා ගනී , නමුත් එක් එම්ඩීඑන් සහාය සඳහා තවමත් අසම්පූර්ණයි - සෆාරි තවමත් තර්ක ඉදිරිපත් කිරීමට සහාය නොදක්වයි toLocaleString.
මාර්ක් අමරි

ArkMarkAmery දැනට, ඇන්ඩ්‍රොයිඩ් බ්‍රව්සරයට පමණක් ගැටළු කිහිපයක් තිබේ: caniuse.com/#search=toLocaleString
ptyskju

11

මෙය සරලම, අලංකාර විසඳුමයි (සහ මම ලෝකයේ හොඳම;):

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

4
Eඅංකනය භාවිතා කර තර්කයක් පිළිගැනීම සඳහා පිළිගත් පිළිතුර නැවත ලිවීමට එය හොඳ ක්‍රමයකි .
ඇක්සෙල් එච්

1
සමහර අවස්ථා වලදී මෙය ක්‍රියා නොකරයි: උත්සාහ කරන්න ( jsfiddle ) roundToX(362.42499999999995, 2). අපේක්ෂිත ප්‍රති result ලය (PHP හි මෙන් echo round(362.42499999999995, 2)) : 362.43. සත්‍ය 362.42
ප්‍රති result ලය

6
IMHO, ඔබගේ PHP ප්‍රති result ලය වැරදිය. තුන්වන දශමයෙන් පසුව කුමක් වුවත්, තුන්වන දශම 5 ට වඩා අඩු නම්, දෙවන දශම එක හා සමාන විය යුතුය. ගණිතමය අර්ථ දැක්වීම එයයි.
සොල්ඩෙප්ලාටා සකෙටෝස්

1
ඊටත් වඩා සංක්ෂිප්ත වීමට නම් “ඊ +” ඒ වෙනුවට “ඊ” විය හැකිය.
ලොනී හොඳම
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.