Nambari kamili ya Javascript na sehemu ya sehemu. Mbinu za kuzungusha nambari katika JavaScript. Kuzungusha epsilon ya mashine

Mara nyingi hesabu hutoa matokeo ambayo yako nje ya safu zinazohitajika. Matokeo yake, ni muhimu kutekeleza Kuzungusha JavaScript hadi thamani fulani.

Kwa nini nambari za pande zote?

JavaScript haihifadhi nambari kamili kwa sababu thamani zake zinawakilishwa kama nambari za sehemu zinazoelea. Sehemu nyingi haziwezi kuwakilishwa kama nambari iliyo na nambari maalum ya kikomo ya maeneo ya desimali, kwa hivyo JavaScript inaweza kutoa matokeo kama yafuatayo:

0.1 * 0.2; > 0.020000000000000004

Kwa mazoezi, hii haitafanya tofauti yoyote, kwani tunazungumza juu ya kosa la 2 quintillionths. Lakini hii inaweza kuathiri matokeo wakati wa kufanya kazi na nambari zinazowakilisha thamani za sarafu, asilimia, au saizi ya faili. Kwa hiyo, unahitaji kufanya au kwa sehemu fulani ya decimal.

Nambari za desimali zinazozunguka

Ili "kukata" nambari ya desimali, tumia toFixed() au toPrecision() mbinu. Wote wawili huchukua hoja moja, ambayo inabainisha idadi ya sehemu muhimu na desimali zitakazojumuishwa kwenye matokeo:

  • ikiwa toFixed() haina hoja iliyobainishwa, thamani chaguo-msingi ni 0, yaani, hakuna sehemu za desimali; thamani ya juu ya hoja ni 20;
  • ikiwa hakuna hoja iliyotolewa kwaPrecision(), nambari haijabadilishwa.

var randNum = 6.25; randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" var randNum = 87.335; randNum.toFixed(2); > "87.33" var randNum = 87.337; randNum.toPrecision(3); > "87.3"

Kumbuka

ToFixed() na toPrecision hurejesha uwakilishi wa mfuatano wa mviringo wa matokeo, badala ya nambari. Hii inamaanisha kuwa kuongeza iliyozungushwa kwa randNum itasababisha muunganisho wa mifuatano badala ya nambari moja:

console.log(randNum + mviringo); > "6.256"

Ikiwa unataka JavaScript kuzungusha nambari hadi mia iliyo karibu zaidi, tumia parseFloat() :

var randNum = 6.25; var rounded = parseFloat(randNum.toFixed(1)); console.log(iliyozunguka); > 6.3

toFixed() na toPrecision() pia ni njia muhimu za kupunguza idadi kubwa ya maeneo ya desimali. Hii ni muhimu wakati wa kufanya kazi na nambari zinazowakilisha vitengo vya fedha:

var wholeNum = 1 var dollarsCents = wholeNum.toFixed(2); console.log(dollarsCents); > "1.00"

Kumbuka kwamba ikiwa nambari ina tarakimu zaidi ya usahihi uliobainishwa, toPrecision itatoa matokeo katika umbizo la kisayansi:

var num = 123.435 num.toPrecision(2); > "1.2e+2"

Jinsi ya kuzuia makosa wakati wa kuzungusha desimali

Katika baadhi ya matukio ya Kusahihisha na kwa Usahihi kutekeleza JavaScript inasogeza 5 chini, na sio zaidi:

var numTest = 1.005; numTest.toFixed(2); > 1;

Matokeo ya mfano hapo juu yanapaswa kuwa 1.01, sio 1. Ikiwa unataka kuzuia kosa hili, ninapendekeza kutumia nambari za kielelezo:

duru ya kazi(thamani, desimali) ( return Number(Math.round(value+"e"+decimals)+"e-"+decimals); )

Maombi:

pande zote(1.005,2); > 1.01

Ikiwa unahitaji suluhisho kali zaidi kuliko kuzungusha, linapatikana MDN.

Kuzunguka na epsilon

Mbinu mbadala JavaScript inazungushwa hadi sehemu ya kumi ilianzishwa katika ES6 ( Pia inajulikana kama JavaScript 2015). « Epsilon ya mashine" hutoa kiwango cha kuridhisha cha makosa wakati wa kulinganisha nambari mbili za sehemu zinazoelea. Bila kuzungusha, kulinganisha kunaweza kutoa matokeo sawa na yafuatayo:

0.1 + 0.2 === 0.3 > uongo

Math.EPSILON inaweza kutumika katika chaguo za kukokotoa kupata ulinganisho halali:

kazi epsEqu(x, y) ( rudisha Math.abs(x - y)< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }

Kazi huchukua hoja mbili: moja ina mahesabu, ya pili matokeo yanayotarajiwa (ya mviringo). Inarudisha kulinganisha kwa vigezo hivi viwili:

epsEqu(0.1 + 0.2, 0.3) > kweli

Vivinjari vyote vya kisasa vinaauni vipengele vya hesabu vya ES6. Lakini ikiwa unahitaji kutoa usaidizi katika vivinjari vya zamani, basi unahitaji kutumia polyfills.

Kukatwa kwa nambari za desimali

Mbinu zote zilizowasilishwa hapo awali zinafanya JavaScript inazungushwa hadi sehemu ya kumi. Ili kupunguza nambari chanya hadi sehemu mbili za desimali, izidishe kwa 100, ipunguze tena, kisha ugawanye matokeo na 100:

kazi iliyopunguzwa(nambari) ( rudisha Math.trunc(num * 100) / 100; ) imepunguzwa (3.1416) > 3.14

Ikiwa unahitaji kitu rahisi zaidi, unaweza kutumia opereta kidogo:

chaguo la kukokotoa limepunguzwa(idadi, Nafasi za decimal) ( var numPowerConverter = Math.pow(10, decimalPlaces); rudisha ~~(num * numPowerConverter)/numPowerConverter; )

Matumizi:

var randInt = 35.874993; kupunguzwa (randInt,3); > 35.874

Zungusha hadi nambari iliyo karibu zaidi

Kutekeleza JavaScript inazungushwa hadi nambari kamili iliyo karibu zaidi, Math.round() inatumika:

Math.round(4.3) > 4 Math.round(4.5) > 5

Kumbuka kwamba " maadili nusu", kama vile .5, zimekusanywa.

Zungusha hadi nambari nzima iliyo karibu zaidi

Ikiwa unataka kupunguza, tumia njia ya Math.floor():

Hesabu.sakafu(42.23); > 42 Math.floor(36.93); > 36

Kurudisha chini kuna mwelekeo mmoja kwa nambari zote, pamoja na zile hasi. Hii inaweza kuzingatiwa kama skyscraper na idadi isiyo na kikomo ya sakafu, pamoja na chini ya kiwango cha msingi ( inayowakilisha nambari hasi) Ikiwa uko kwenye lifti kati ya sakafu ya chini ya 2 na 3 ( ambayo inalingana na thamani ya -2.5), Math.floor itakupeleka kwenye sakafu -3:

Hesabu.sakafu(-2.5); > -3

Ikiwa unahitaji kuepuka hili, tumia JavaScript Math rounding kwa kutumia Math.trunc() , inayotumika katika vivinjari vyote vya kisasa (isipokuwa IE/Edge):

Math.trunc(-41.43); > -41

MDN pia hutoa ujazo wa mistari-tatu ili kutoa usaidizi kwa Math.trunc katika vivinjari vya zamani na IE/Edge.

Zungusha hadi nambari nzima iliyo karibu zaidi

Ikiwa ungependa kuongeza nambari za desimali, tumia Math.ceil . Njia hii pia inaweza kuzingatiwa kama lifti isiyo na kikomo: Math.ceil inakupeleka "juu", bila kujali ikiwa nambari ni hasi au chanya:

Math.ceil(42.23); > 43 Math.ceil(36.93); > 37 Math.ceil(-36.93); -36

Zungusha hadi nyingi zilizo karibu

Ikiwa unahitaji kuzungusha thamani kwa kizidishio cha karibu zaidi cha 5, unda chaguo la kukokotoa ambalo linagawanya nambari na 5, kuizungusha, na kisha kuzidisha matokeo kwa thamani sawa:

kazi roundTo5(num) ( return Math.round(num/5)*5; )

Matumizi:

roundTo5(11); > 10

Ikiwa unahitaji JavaScript kuzungusha hadi nambari mbili, unaweza kupitisha mbegu na nyingi kwa kazi:

kazi roundToMultiple(idadi, nyingi) ( return Math.round(num/multiple)*multiple; )

Ili kutumia chaguo la kukokotoa, jumuisha nambari ya kuzungushwa na nambari katika simu yake:

var initialNamba = 11; var nyingi = 10; roundToMultiple(Nambari ya awali, nyingi); > 10;

Ili kuzungusha thamani juu au chini pekee, badilisha pande zote na dari au sakafu kwenye chaguo za kukokotoa.

Kufunga safu

Wakati mwingine unahitaji kupata thamani ya x ambayo lazima iwe ndani ya masafa fulani. Kwa mfano, tunahitaji thamani kutoka 1 hadi 100, lakini tunapata thamani 123. Ili kurekebisha hii unaweza kutumia min() ( inarudisha nambari ndogo zaidi) na max ( hurejesha idadi ya juu inayoruhusiwa).

Matumizi:

var lowBound = 1; var highBound = 100; var numInput = 123; var clamped = Math.max(lowBound, Math.min(numInput, highBound)); console.log(iliyobanwa); > 100;

Unaweza kuunda kitendakazi au upanuzi wa darasa la Nambari.

Hii hukuruhusu kurekebisha jibu la @MarkElliot ili ifanye kazi kwa nambari hasi pia:

Var div = Math.trunc(y/x); var rem = y % x;

Kumbuka kuwa mbinu za Hisabati zina faida zaidi ya waendeshaji bitwise kwamba wanafanya kazi na nambari kubwa kuliko 2 31 .

JavaScript hukokotoa upande wa kulia jinsia ya nambari hasi na salio la nambari zisizo nambari kamili, kufuatia ufafanuzi wa hisabati kwao.

FLOOR inafafanuliwa kama "nambari kamili chini ya parameta", kwa hivyo:

  • nambari chanya: FLOOR(X) = sehemu kamili ya X;
  • nambari hasi: FLOOR(X) = sehemu kamili ya X minus 1 (kwa sababu inapaswa kuwa NDOGO kuliko kigezo, yaani hasi zaidi!)

REMAINDER inafafanuliwa kama mgawanyiko "uliosalia" (hesabu ya Euclidean). Wakati gawio sio nambari kamili, sababu kawaida pia sio nambari kamili, i.e. hakuna salio, lakini ikiwa sababu italazimishwa kuwa nambari kamili (na hii ndio hufanyika wakati mtu anajaribu kupata salio au moduli ya a. nambari ya sehemu inayoelea ), ni wazi kutakuwa na nambari kamili "kushoto".

JavaScript huhesabu kila kitu kama inavyotarajiwa, kwa hivyo mpangaji programu lazima awe mwangalifu kuuliza maswali sahihi (na watu lazima wawe waangalifu kujibu kile kinachoulizwa!) Swali la kwanza la Yarin HAIKUWA "mgawanyiko kamili wa X na Y ni nini", badala ya hili: "Nambari kamili ya mara nambari kamili INAENDA KWA nyingine." Kwa nambari chanya, jibu ni sawa kwa zote mbili, lakini sio kwa nambari hasi, kwa sababu mgawanyiko kamili (mgawanyiko na mgawanyiko) utakuwa -1 chini ya nambari (kigawanyiko) "inazunguka" (gawio). Kwa maneno mengine, FLOOR itarudisha jibu sahihi kwa mgawanyiko kamili wa nambari hasi, lakini Yarin hakuuliza juu ya hilo!

gammax imejibu kwa usahihi, nambari hii inafanya kazi kulingana na maagizo ya Yarin. Kwa upande mwingine, Samweli ana makosa, hakufanya hesabu ninayodhani, au angeona kuwa hii inafanya kazi (pia hakusema kigawanyaji cha mfano wake kilikuwa nini, lakini natumai ilikuwa 3) :

Iliyobaki = X% Y = -100% 3 = -1

GoesInto = (X - Salio) / Y = (-100 - -1) / 3 = -99 / 3 = -33

Kwa njia, nilijaribu msimbo kwenye Firefox 27.0.1, ilifanya kazi kama inavyotarajiwa na nambari chanya na hasi, pamoja na maadili yasiyo ya jumla, kwa gawio na vigawanyiko. Mfano:

100.34 / 3.57: GoesInto = -28, Salio = -0.38000000000000079

Ndio, niligundua kuwa kuna shida na usahihi wa hali ya juu, lakini sikuwa na wakati wa kuiangalia (sijui ikiwa ni shida na Firefox, Windows 7, au FPU yangu ya CPU). Walakini, kwa swali la Yarin, ambalo linajumuisha nambari kamili tu, nambari ya gammax inafanya kazi vizuri.

Unaweza kutumia kitendakazi cha parseInt kupata matokeo yaliyopunguzwa.

Changanua(a/b)

Ili kupata salio, tumia opereta ya mod:

parseInt ina mitego iliyo na kamba ili kuzuia kutumia parameta ya radix iliyo na msingi 10.

ParseInt("09", 10)

Katika baadhi ya matukio, uwakilishi wa mfuatano wa nambari unaweza kuwa nukuu ya kisayansi, ambapo parseInt itatoa matokeo yasiyo sahihi.

ParseInt(10000000000000000000000000000000, 10) // 1e+32

Simu hii itatoa matokeo 1.

Kuhesabu idadi ya kurasa kunaweza kufanywa kwa hatua moja: Math.ceil(x/y)

Ikiwa unashiriki tu nguvu za wawili, unaweza kutumia waendeshaji kidogo:

Hamisha kipengele cha chaguo za kukokotoa divideBy2(num) ( return ; ) export kitendakazi divideBy4(num) ( return ; ) export kitendakazi divideBy8(num) ( return ; )

(Ya kwanza ni maalum, ya pili ni iliyobaki)

Hii itapunguza hadi sifuri kila wakati. Sina hakika kama imechelewa, lakini inasema hapa:

Kazi intdiv(gawio, kigawanyiko) ( kigawanyiko = kigawanyaji - kigawanya % 1; ikiwa (kigawanya == 0) tupa Hitilafu mpya("mgawanyiko kwa sifuri"); mgao = mgao - mgao % 1; var rem = mgawanyiko% wa mgawanyiko; kurudi ( salio: rem, quotient: (dividend - rem) / divisor)

Mimi sio mtaalam wa waendeshaji kidogo, lakini hapa kuna njia nyingine ya kupata nambari kamili:

Var num = ~~(a / b);

Hii itafanya kazi vizuri kwa nambari hasi pia, wakati Math.floor() itazunguka katika mwelekeo mbaya.

Hii pia inaonekana kuwa sawa:

Var num = (a / b) >> 0;

Math.floor(operation) hurejesha thamani iliyozungushwa ya operesheni.

Mfano wa swali la 1:

Var x = 5; var y = 10.4; var z = Math.floor(x + y); console.log(z);

Console:

Mfano wa swali la 2:

Var x = 14; var y = 5; var z = Math.floor(x%y); console.log(x);

Console:

Kwa nambari fulani y na kigawanyaji x, hesabu mgawo na salio (salio) kama:

Var quotient = Math.floor(y/x); var salio = y % x;

Mara nyingi, mahesabu katika JavaScript haitoi matokeo tunayotaka. Kwa kweli, tunaweza kufanya chochote tunachotaka na nambari - kuzunguka juu au chini, kuweka safu, kukata nambari zisizo za lazima kwa idadi fulani ya maeneo ya desimali, yote inategemea kile unachotaka kufanya katika siku zijazo na nambari hii.

Kwa nini kuzungusha kunahitajika?

Mojawapo ya mambo ya kuvutia ya JavaScript ni kwamba haihifadhi nambari kamili, tunafanya kazi mara moja na nambari za sehemu zinazoelea. Hii, pamoja na ukweli kwamba maadili mengi ya sehemu hayawezi kuonyeshwa kwa idadi ndogo ya maeneo ya decimal, katika JavaScript tunaweza kupata matokeo kama haya:

0.1 * 0.2; > 0.020000000000000004 0.3 - 0.1 > 0.19999999999999998
Kwa madhumuni ya vitendo usahihi huu haujalishi, kwa upande wetu tunazungumza juu ya kosa katika quintillionths, hata hivyo, hii inaweza kuwakatisha tamaa wengine. Tunaweza pia kupata matokeo ya kushangaza tunapofanya kazi na nambari zinazowakilisha sarafu, asilimia au saizi za faili. Ili kurekebisha makosa haya, tunahitaji tu kuwa na uwezo wa kuzunguka matokeo, na inatosha kuweka usahihi wa decimal.

Nambari za mzunguko zina matumizi ya vitendo, tunaweza kudanganya nambari ndani ya safu fulani, kwa mfano tunataka kuzungusha thamani hadi nambari nzima iliyo karibu zaidi kuliko kufanya kazi na sehemu ya desimali pekee.

Nambari za desimali zinazozunguka

Ili kunakili nambari ya desimali, tumia Fixed au toPrecision mbinu. Zote mbili huchukua hoja moja inayobainisha, mtawaliwa, ni tarakimu ngapi muhimu (yaani, jumla ya nambari zinazotumiwa katika nambari hiyo) au maeneo ya desimali (idadi baada ya nukta ya desimali) matokeo yanapaswa kujumuisha:
  1. Ikiwa hoja haijafafanuliwa kwa toFixed(), itabadilika kuwa sifuri, ambayo inamaanisha nafasi 0 za desimali, hoja hiyo ina thamani ya juu zaidi ya 20.
  2. Ikiwa hakuna hoja iliyotolewa kwaPrecision, nambari itaachwa bila kuguswa
basi randNum = 6.25; randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" randNum = 87.335; randNum.toFixed(2); > "87.33" randNum = 87.337; randNum.toPrecision(3); > "87.3"
Njia zote mbili toFixed() na toPrecision() zinarudisha uwakilishi wa matokeo, sio nambari. Hii inamaanisha kuwa wakati wa kujumlisha thamani iliyo na mviringo na randNum, itatoa muunganisho wa mifuatano badala ya jumla ya nambari:

Hebu randNum = 6.25; acha kuzungushwa = randNum.toFixed(); // "6" console.log(randNum + mviringo); > "6.256"
Ikiwa unataka matokeo kuwa aina ya data ya nambari, basi utahitaji kutumia parseFloat:

Hebu randNum = 6.25; acha kuzungushwa = parseFloat(randNum.toFixed(1)); console.log(iliyozunguka); > 6.3
Tafadhali kumbuka kuwa thamani ya 5 ni mviringo isipokuwa katika hali nadra.

Njia za toFixed() na toPrecision() ni muhimu kwa sababu haziwezi tu kukata sehemu ya sehemu, lakini pia kuongeza maeneo ya decimal, ambayo ni rahisi wakati wa kufanya kazi na sarafu:

Hebu wholeNum = 1 acha dollarsCents = wholeNum.toFixed(2); console.log(dollarsCents); > "1.00"
Kumbuka kuwa toPrecision itatoa matokeo katika nukuu ya kisayansi ikiwa nambari kamili ni kubwa kuliko usahihi yenyewe:

Hebu nambari = 123.435 num.toPrecision(2); > "1.2e+2"

Jinsi ya Kuepuka Makosa ya Kuzungusha na Desimali

Katika hali zingine, Kurekebisha na kwa Usahihi huzungusha thamani 5 chini na juu:

Hebu numTest = 1.005; numTest.toFixed(2); > "1.00"
Matokeo ya hesabu hapo juu yanapaswa kuwa 1.01, sio 1. Ikiwa unataka kuepuka kosa sawa, tunaweza kutumia suluhisho lililopendekezwa na Jack L Moore, ambalo linatumia nambari za kielelezo kwa hesabu:

Duru ya kazi(thamani, desimali) ( rudisha Nambari(Math.round(value+"e"+decimals)+"e-"+decimals);)
Sasa:

Mzunguko (1.005,2); > 1.01
Ikiwa unataka suluhisho thabiti zaidi kuliko lililoonyeshwa hapo juu, unaweza kwenda kwa MDN.

Kuzungusha epsilon ya mashine

Mbinu mbadala ya kuzungusha nambari za desimali ilianzishwa katika ES6. Kuzungusha epsilon ya mashine hutoa ukingo unaofaa wa makosa wakati wa kulinganisha nambari mbili za sehemu zinazoelea. Bila kuzungusha, kulinganisha kunaweza kutoa matokeo sawa na yafuatayo:

0.1 + 0.2 === 0.3 > uongo
Tunatumia Math.EPSILON katika utendaji wetu ili kupata ulinganisho halali:

Kazi epsEqu(x, y) ( rudisha Math.abs(x - y)< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
Kazi inachukua hoja mbili: ya kwanza ni hesabu ya sasa, ya pili ni matokeo yanayotarajiwa. Inarudisha ulinganisho wa hizo mbili:

EpsEqu(0.1 + 0.2, 0.3) > kweli
Vivinjari vyote vya kisasa tayari vinaauni vipengele vya hesabu vya ES6, lakini ikiwa unataka usaidizi katika vivinjari kama vile IE 11, tumia kujaza aina nyingi.

Kupunguza sehemu ya sehemu

Njia zote zilizowasilishwa hapo juu zinaweza kuzunguka hadi nambari za desimali. Ili kukata nambari hadi sehemu mbili za decimal, lazima kwanza uzidishe kwa 100, na kisha ugawanye matokeo na 100:

Chaguo la kukokotoa limepunguzwa(nambari) ( rudisha Math.trunc(num * 100) / 100; ) imepunguzwa (3.1416) > 3.14
Ikiwa unataka kurekebisha njia kwa idadi yoyote ya maeneo ya decimal, unaweza kutumia ukanushaji mara mbili wa bitwise:

Chaguo la kukokotoa limepunguzwa(idadi, Sehemu za decimal) ( acha numPowerConverter = Math.pow(10, decimalPlaces); rudisha ~~(num * numPowerConverter)/numPowerConverter; )
Sasa:

Hebu randInt = 35.874993; kupunguzwa (randInt,3); > 35.874

Zungusha hadi nambari iliyo karibu zaidi

Ili kuzungusha nambari ya desimali hadi nambari iliyo karibu zaidi juu au chini, haijalishi ni ipi tuliyo karibu nayo, tumia Math.round():

Math.round(4.3) > 4 Math.round(4.5) > 5
Tafadhali kumbuka kuwa "nusu ya thamani", 0.5 imezungushwa kulingana na sheria za hisabati.

Zungusha hadi nambari nzima iliyo karibu zaidi

Ikiwa unataka kupunguza kila wakati, tumia Math.floor:

Hesabu.sakafu(42.23); > 42 Math.floor(36.93); > 36
Tafadhali kumbuka kuwa kufupisha hufanya kazi kwa nambari zote, pamoja na nambari hasi. Hebu fikiria skyscraper yenye idadi isiyo na kipimo ya sakafu, ikiwa ni pamoja na sakafu kwenye ngazi ya chini (inayowakilisha namba hasi). Ikiwa uko kwenye lifti kwenye kiwango cha chini kabisa kati ya 2 na 3 (ambayo inawakilisha thamani ya -2.5), Math.floor itakupeleka hadi -3:

Hesabu.sakafu(-2.5); > -3
Lakini ikiwa unataka kuepuka hali hii, tumia Math.trunc, inayotumika katika vivinjari vyote vya kisasa (isipokuwa IE/Edge):

Math.trunc(-41.43); > -41
Kwenye MDN utapata ujazo wa aina nyingi ambao utatoa msaada kwa Math.trunc katika vivinjari na IE/Edge.

Zungusha hadi nambari nzima iliyo karibu zaidi

Kwa upande mwingine, ikiwa unahitaji kukusanya kila wakati, tumia Math.ceil. Tena, kumbuka lifti isiyo na kikomo: Math.ceil itaenda "juu" kila wakati, bila kujali ikiwa nambari ni hasi au la:

Math.ceil(42.23); > 43 Math.ceil(36.93); > 37 Math.ceil(-36.93); > -36

Inazungusha juu/chini hadi nambari inayohitajika

Ikiwa tunataka kuzungusha kwa kizidishio cha karibu zaidi cha 5, njia rahisi ni kuunda chaguo la kukokotoa ambalo linagawanya nambari na 5, kuizungusha, na kisha kuizidisha kwa kiwango sawa:

Kazi roundTo5(num) ( rudisha Math.round(num/5)*5; )
Sasa:

MzungukoTo5(11); > 10
Iwapo ungependa kuzungusha hadi vizidishio vya thamani yako, tunatumia chaguo la kukokotoa la jumla zaidi, tukipitisha thamani ya awali na nyingi:

Kazi roundToMultiple(idadi, nyingi) ( return Math.round(num/multiple)*multiple; )
Sasa:

Acha Nambari ya mwanzo = 11; acha nyingi = 10; roundToMultiple(Nambari ya awali, nyingi); > 10;

Inarekebisha nambari katika safu

Kuna matukio mengi ambapo tunataka kupata thamani ya x ambayo iko ndani ya masafa. Kwa mfano, tunaweza kuhitaji thamani kati ya 1 na 100, lakini tukaishia na thamani ya 123. Ili kurekebisha hili, tunaweza kutumia min (hurejesha nambari ndogo zaidi ya seti ya nambari) na max (hurejesha kubwa zaidi ya seti yoyote. ya nambari). Katika mfano wetu, anuwai ni kutoka 1 hadi 100:

Hebu lowBound = 1; basi highBound = 100; acha numInput = 123; acha imefungwa = Math.max(lowBound, Math.min(numInput, highBound)); console.log(iliyobanwa); > 100;
Tena, tunaweza kutumia tena utendakazi na kufunga jambo zima katika utendaji, kwa kutumia suluhisho lililopendekezwa na Daniel X. Moore:

Number.prototype.clamp = function(min, max) ( rudisha Math.min(Math.max(hii, min), max); );
Sasa:

NumInput.clamp(LowBound, highBound); > 100;

Mzunguko wa Gaussian

Mzunguko wa Gaussian, unaojulikana pia kama uwekaji wa benki, unahusisha kuzungusha hadi nambari sawia iliyo karibu zaidi. Njia hii ya kuzungusha inafanya kazi bila hitilafu ya takwimu. Suluhisho bora lilipendekezwa na Tim Down:

Kazi ya gaussRound(idadi, Nafasi za decimal) ( let d = decimalPlaces || 0, m = Math.pow(10, d), n = +(d ? num * m: num).toFixed(8), i = Math.floor (n), f = n - i, e = 1e-8, r = (f > 0.5 - e && f< 0.5 + e) ? ((i % 2 == 0) ? i: i + 1) : Math.round(n); return d ? r / m: r; }
Sasa:

Mzunguko wa Gauss(2.5) > 2 gaussRound(3.5) > 4 gaussRound(2.57,1) > 2.6
Desimali katika CSS:

Kwa kuwa JavaScript mara nyingi hutumiwa kuunda upangaji wa mpangilio wa vipengee vya HTML, unaweza kuwa unajiuliza nini kitatokea ikiwa tungetoa maadili ya desimali kwa vipengele vyetu:

#sanduku ( upana: 63.667731993px; )
Habari njema ni kwamba vivinjari vya kisasa vitaheshimu maadili ya desimali katika muundo wa block, pamoja na asilimia au vitengo vya pixel.

Inapanga

Mara nyingi sana tunapaswa kupanga baadhi ya vipengele, kwa mfano, tuna safu ya rekodi za mchezo, na lazima zipangwa kwa mpangilio wa kushuka wa kiwango cha wachezaji. Kwa bahati mbaya, njia ya kawaida ya sort() ina mapungufu ya kushangaza: inafanya kazi vizuri na maneno ya kawaida ya Kiingereza, lakini huvunjika mara moja inapokutana na nambari, herufi za kipekee, au maneno makubwa.

Kupanga kwa alfabeti

Inaweza kuonekana kuwa kupanga safu kialfabeti inapaswa kuwa kazi rahisi:

Hebu matunda = ["butternut squash", "apricot", "cantaloupe"]; matunda.aina(); > "apricot", "butternut squash", "cantaloupe"]
Walakini, tunakumbana na shida mara tu moja ya vipengee viko katika herufi kubwa:

Hebu matunda = ["butternut squash", "apricot", "Cantalope"]; matunda.aina(); > "Cantaloupe", "apricot", "butternut boga"]
Hii ni kwa sababu, kwa chaguo-msingi, kipangaji hulinganisha herufi ya kwanza inayowakilishwa katika Unicode. Unicode ni msimbo wa kipekee kwa mhusika yeyote, bila kujali jukwaa, bila kujali programu, bila kujali lugha. Kwa mfano, ukiangalia jedwali la msimbo, herufi "a" ina thamani U+0061 (katika hexadecimal 0x61), wakati herufi "C" ina msimbo U+0043 (0x43), ambayo inakuja mapema katika Unicode. meza kuliko mhusika "a".

Ili kupanga safu ambayo inaweza kuwa na herufi mchanganyiko za herufi za kwanza, tunahitaji ama kubadilisha vipengele vyote kwa muda hadi herufi ndogo, au kufafanua mpangilio wetu wa kupanga kwa kutumia localeCompare() mbinu na baadhi ya hoja. Kama sheria, kwa kesi kama hiyo, ni bora kuunda kazi mara moja kwa matumizi ya mara kwa mara:

Fanya kazi alphaSort(arr) ( arr.sort(function (a, b) ( return a.localeCompare(b, "en", ("sensitivity": "base")); )); acha matunda = ["butternut squash ", "apricot", "Cantaloupe"]; alphaAina(matunda) >
Ikiwa unataka safu kupangwa kwa mpangilio wa alfabeti ya kinyume, badilisha tu nafasi za a na b katika chaguo la kukokotoa:

Kazi alphaSort(arr) ( arr.sort(function (a, b) ( return b.localeCompare(a, "en", ("sensitivity": "base")); )); acha matunda = ["butternut squash ", "apricot", "Cantaloupe"]; alphaSort(matunda) > ["Cantaloupe", "butternut squash", "apricot"]
Hapa inafaa kuzingatia kwamba localeCompare inatumiwa na hoja, tunahitaji pia kukumbuka kuwa inaungwa mkono na IE11+, kwa matoleo ya zamani ya IE, tunaweza kuitumia bila hoja, na kwa herufi ndogo:

Kesi ya kaziPanga(arr) ( arr.sort(function (a, b) ( return a.toLowerCase().localeCompare(b.toLowerCase()); )); ) acha matunda = ["butternut squash", "apricot", "Cantaloupe"]; kesiPanga(matunda) > ["apricot", "butternut squash", "Cantaloupe"]

Aina ya nambari

Yote hii haitumiki kwa mfano tuliozungumzia hapo juu kuhusu safu ya rekodi za mchezo. Na safu kadhaa za nambari, kupanga hufanya kazi vizuri, lakini wakati fulani matokeo yanaweza kuwa yasiyotabirika:

Hebu highScores =; highScores.sort(); >
Jambo ni kwamba sort() njia hufanya ulinganisho wa leksikografia: ambayo inamaanisha kuwa nambari zitabadilishwa kuwa kamba na ulinganisho utafanywa tena kwa kulinganisha herufi ya kwanza ya kamba hiyo kwa mpangilio wa herufi kwenye jedwali la Unicode. . Kwa hivyo, tunahitaji tena kufafanua mpangilio wetu wa aina:

Hebu highScores =; highScores.sort(kazi(a,b) ( rudisha a - b; )); >
Tena, kupanga nambari kwa mpangilio wa nyuma, badilisha nafasi za a na b katika chaguo la kukokotoa.

Inapanga muundo unaofanana na JSON

Na hatimaye, ikiwa tuna muundo wa data unaofanana na JSON unaowakilishwa kama safu ya rekodi za mchezo:

Acha alama = [ ( "name": "Daniel", "score": 21768 ), ( "name": "Michael", "score": 33579 ), ( "name": "Alison", "score": 38395 )];
Katika ES6+, unaweza kutumia vitendaji vya mshale:

Alama.panga((a, b) => b.alama - a.alama));
Kwa vivinjari vya zamani ambavyo havina usaidizi huu:

Alama.panga(kazi(a, b) (rejesha a.alama - b.alama));
Kama unavyoona, kupanga katika JavaScript ni jambo lisilojulikana, natumai kuwa mifano hii itafanya maisha kuwa rahisi kwa njia fulani.

Kufanya kazi na kazi za nguvu

Ufafanuzi ni operesheni iliyofafanuliwa awali kama matokeo ya kuzidisha nambari asilia yenyewe mara kwa mara; Tunaweza kutumia vipengele hivi kila mara katika maisha ya kila siku katika masomo ya hisabati, ikiwa ni pamoja na wakati wa kukokotoa maeneo, juzuu, au hata katika uundaji wa kimwili.

Katika JavaScript, kipengele cha kufanya kazi cha nguvu kinawakilishwa kama Math.pow(), na katika kiwango kipya cha ES7, mwendeshaji mpya wa udhihirisho ulianzishwa - " * *".

Ufafanuzi

Ili kuongeza nambari hadi nguvu ya nth, tumia chaguo za kukokotoa za Math.pow(), ambapo hoja ya kwanza ni nambari ambayo itatolewa kwa nguvu, hoja ya pili ni kipeo.

Hesabu.pow(3,2) > 9
Aina hii ya nukuu inamaanisha 3 mraba, au 3 × 3, ambayo husababisha matokeo 9. Mfano mwingine unaweza kutolewa, bila shaka:

Hesabu.pow(5,3); > 125
Hiyo ni, mchemraba 5, au 5 × 5 × 5, ni sawa na 125.

ECMAScript 7 ni toleo linalofuata la JavaScript, kimsingi, tunaweza kutumia opereta mpya ya ufafanuzi inayopendekezwa - * *, aina hii ya nukuu inaweza kufafanua zaidi:

3 ** 2 > 9
Kwa sasa, msaada kwa operator hii ni mdogo kabisa, hivyo matumizi yake hayapendekezi.

Kazi ya nguvu inaweza kuwa na manufaa katika hali mbalimbali. Mfano rahisi, kuhesabu idadi ya sekunde katika saa: Math.pow (60,2).

Mraba na mizizi ya mchemraba

Math.sqrt() na Math.cbrt() ni kinyume cha Math.pow(). Kama tunavyokumbuka, mzizi wa mraba wa a ni nambari inayotoa wakati ikiwa mraba.

Hesabu.sqrt(9) > 3
Wakati huo huo, mzizi wa mchemraba wa a ni nambari ambayo inatoa wakati imeinuliwa kwa mchemraba.

Hisabati.cbrt(125) > 5
Math.cbrt() ilianzishwa hivi majuzi tu katika vipimo vya JavaScript, na kwa hivyo inatumika tu katika vivinjari vya kisasa: Chrome 38+, Firefox na Opera 25+, na Safari 7.1+. Utagundua kuwa Internet Explorer haipo kwenye orodha hii, lakini utapata ujazo wa aina nyingi kwenye MDN.

Mifano

Kwa kweli, tunaweza kutumia maadili yasiyo kamili katika mojawapo ya kazi hizi:

Hesabu.pow(1.25, 2); > 1.5625 Math.cbrt(56.57) > 3.8387991760286138
Tafadhali kumbuka kuwa hii pia inafanya kazi vizuri wakati wa kutumia maadili hasi ya hoja:

Hesabu.pow(-5,2) > 25 Math.pow(10,-2) > 0.01
Walakini, hii haitafanya kazi kwa mzizi wa mraba:

Math.sqrt(-9) > NaN
Kutoka kwa uchanganuzi wa hisabati tunajua kuwa nambari ya kufikiria inarejelea mizizi ya mraba ya nambari hasi. Na hii inaweza kutuongoza kwa mbinu nyingine ya kufanya kazi na nambari changamano, lakini hiyo ni hadithi nyingine.

Unaweza kutumia sehemu katika Math.pow() kupata mizizi ya mraba na mchemraba wa nambari. Mizizi ya mraba hutumia kipeo cha 0.5:

Hesabu.pow(5, 0.5); // = Hisabati.sqrt(5) = 5 ** (1/2) > 2.23606797749979
Walakini, kwa sababu ya mabadiliko ya sehemu ya kuelea, huwezi kukisia matokeo sahihi:

Hesabu.pow(2.23606797749979,2) > 5.000000000000001
Katika hali kama hizi, itabidi uamue kukata ishara kutoka kwa nambari au kuzungusha hadi thamani fulani.

Baadhi ya watu, kwa sababu zisizojulikana, katika JavaScript huchanganya kazi ya Math.pow() na Math.exp() , ambayo ni chaguo la kukokotoa la nambari kwa ujumla. Kumbuka: Kwa Kiingereza, "kielezi" kinatafsiriwa kama "kielezi", kwa hivyo hii ina uwezekano mkubwa wa kutumika kwa wazungumzaji wa Kiingereza, ingawa kuna majina mbadala ya kielezi, kama vile fahirisi, nguvu.

Vipengele vya hisabati

Kufanya kazi na hisabati katika JavaScript kunarahisishwa na idadi ya vidhibiti vilivyojengwa ndani. Vipengele hivi ni mali ya kitu cha Math. Inafaa kumbuka kuwa viunga vimeandikwa kwa herufi kubwa, sio nukuu ya CamelCase.

Math.abs, parseInt, parseFloat

Kufanya kazi na nambari kwenye JavaScript inaweza kuwa ngumu zaidi kuliko inavyoonekana. Thamani zilizopatikana haziingii ndani ya safu zinazotarajiwa wakati mwingine matokeo yanaweza yasiwe kama tulivyotarajia.

Hisabati.abs()

Mbinu ya Math.abs() hurejesha thamani kamili ya nambari, ambayo hutukumbusha kazi sawa ya hisabati ya moduli ya nambari.

Hebu newVal = -57.64; Hisabati.abs(newVal); > 57.64
Math.abs(0) hurejesha sufuri kila wakati, lakini tukiweka alama ya kuondoa mbele ya chaguo za kukokotoa -Math.abs(NUM) tutapata thamani hasi kila wakati.

Hisabati.abs(0); > -0

parseInt()

Tunajua kuwa JavaScript inaelewa kuwa "15" ni mfuatano, si nambari, na, kwa mfano, wakati wa kuchanganua sifa za CSS kwa kutumia JavaScript, au kupokea thamani kutoka kwa safu ambayo haijatayarishwa, matokeo yetu yanaweza kuwa yasiyotabirika. Tunaweza kupokea mfuatano unaowakilishwa kama "17px" kama ingizo, na hili si jambo la kawaida kwetu. Swali ni jinsi ya kubadilisha kamba hii kuwa thamani halisi na kuitumia katika mahesabu zaidi.

Sintaksia: parseInt(kamba, radix);

Chaguo za kukokotoa za parseInt hubadilisha hoja ya kwanza iliyopitishwa kwake kuwa aina ya mfuatano, kuifasiri, na kurudisha thamani kamili au NaN. Matokeo (kama si NaN) ni nambari kamili na ni hoja ya kwanza (kamba), inayochukuliwa kama nambari katika radix iliyobainishwa. Kwa mfano, msingi wa 10 unaonyesha ubadilishaji kutoka kwa decimal, 8 kutoka octal, 16 kutoka hexadecimal, na kadhalika. Ikiwa msingi ni mkubwa kuliko 10, basi herufi hutumiwa kuwakilisha nambari kubwa kuliko 9. Kwa mfano, kwa nambari za hexadecimal (msingi 16), barua A hadi F hutumiwa.

Wacha tuangalie mfano wa kufanya kazi na mali ya CSS, ambapo, kwa kusema, tunaweza kupata dhamana ifuatayo:

Hebu elem = document.body; let centerPoint = window.getComputedStyle(elem).transformOrigin; > "454px 2087.19px"
Tunaweza kugawanya maadili kwa nafasi:

Acha vituo = centerPoint.split(" "); > ["454px", "2087.19px"]
Walakini, kila kipengele bado ni kamba, tunaweza kuiondoa kwa kutumia kazi yetu:

Acha centerX = parseInt(vituo, 10); > 454 let centerY = parseInt(vituo, 10); >2087
Kama unaweza kuona, na hoja ya pili tunaonyesha mfumo wa nambari ambayo nambari itabadilishwa;

parseFloat()

Kutoka kwa mfano hapo juu, labda umegundua kuwa parseInt inatupa sehemu ya sehemu. Kwa upande wetu, parseFloat inaweza kufanya kazi na nambari za sehemu zinazoelea. Tena, hii inaweza kuwa muhimu wakati wa kuchanganua CSS na kazi nyingine, hasa wakati wa kufanya kazi na asilimia ya pointi zinazoelea.

Sintaksia: changanuaFloat(kamba)

Hebu FP = "33.33333%"; console.log(parseFloat(FP)); > 33.33333
Kumbuka kuwa hakuna hoja ya pili katika syntax ya parseFloat.

Ingawa tunaelewa kuwa parseInt() na parseFloat() ni vitendaji muhimu sana, ni muhimu kukumbuka kuwa hazina makosa, kwa hivyo ni muhimu kuangalia anuwai ya maadili yanayotarajiwa na mwishowe kuchambua matokeo ili kuhakikisha. kwamba maadili yaliyopatikana ni sahihi.
Tuma bila kujulikana


Katika sehemu hii ya masomo yetu tutafahamiana na kitu Nambari kama ilivyo kwa chombo cha aina ya data ya nambari. Kiini chake halisi cha lengo kitaguswa juu juu sana leo.

Sawa na kitu Kamba ina mistari ya maandishi, kitu Nambari ina nambari. Kama vile tungo, nambari tunazounda kiotomatiki huwa mifano ya kitu.

Nambari ya aina ya data

Nambari katika JavaScript huja katika aina mbili: nambari kamili na sehemu ya kuelea (hakuna mgawanyiko katika aina nyingi, kama katika lugha zingine nambari kamili, ndefu, fupi, mbili). Nambari za sehemu zinazoelea zina sehemu kamili na za sehemu zilizotenganishwa na nukta (bila kujali mipangilio ya eneo).

Aina hizi mbili za nambari sio aina za kujitegemea na hazihitaji uongofu maalum kati yao wenyewe. Ikiwa, kwa mfano, 32.5 tutazidisha 0.4 , basi mara moja tunapata nambari kamili 13 , sio sehemu 13.0 , ambayo inahitaji kubadilishwa hadi thamani kamili (kama kawaida katika lugha zingine).

Kuunda kitu cha Nambari

Kama kamba, nambari kawaida huidhinishwa kama kitu Nambari, mgawo rahisi (tofauti na kamba, hakuna nukuu zinazohitajika).

var myNum = 21;

Lakini pia unaweza kuunda kitu kipya kwa kutumia mjenzi:

var myNum = Nambari mpya; myNum = 21;

Katika hali nyingi, hii sio lazima na hata inadhuru. Tutaangalia mifano sahihi ya kazi kama hiyo na vitu katika Sehemu ya 4.

Uwakilishi wa nambari

Fomu ya kielelezo

Nambari zinaweza kuwakilishwa kwa njia ya kawaida au ya kielelezo, kwa mfano:

2e6 // hakuna nafasi!

Inamaanisha: 2 × 10 6

Ikiwa tutatoa nambari kama hiyo kupitia njia ya hati andika(), basi tunapata nambari iliyopanuliwa katika uwakilishi wa kawaida.

Hati. andika(14e12);

Matokeo:

Mifumo ya nambari ya msingi

Nambari pia zinaweza kuwakilishwa katika mifumo ya desimali, hexadecimal na octal.

Nzima nambari katika fomu ya desimali haipaswi kuanza kutoka mwanzo, kwa sababu sufuri ni kiambishi awali cha mifumo isiyo ya decimal. Tu 0 kiambishi awali cha maadili ya octal, na 0x kwa hexadecimal.

Kwa mfano, 075 ni uwakilishi oktali wa nambari ya desimali 61 , A 0x75 uwakilishi wa heksadesimali wa nambari ya desimali 117 .

Kwa thamani za octal, nambari kutoka 0 kabla 7 , kwa mfululizo wa hexadecimal alphanumeric 0123456789ABCDEF. Barua zinaweza kutumika katika rejista yoyote.

Semi za hesabu zinaweza kutumia aina yoyote ya nambari, lakini matokeo yatawakilishwa kama nambari ya desimali kila wakati.

Uwakilishi wa nambari katika mifumo mingine

Akizungumza kuhusu kitu Kamba, tuligusia njia toString(), ambayo hubadilisha kitu chochote kuwa kamba. Wakati wa kubadilisha nambari kwa kamba, inashauriwa kutaja mfumo wa nambari kama hoja.

Kumbuka

Nambari asili lazima iwekwe kwenye mabano

(idadi). kwaString(mfumo)

mfumo inaweza kuchukua thamani yoyote kutoka 2 hadi 36.

(157 ).kwaString(2 ); // uwakilishi wa binary 157, sawa (53 ).kwaString(27 ); // uwakilishi wa kigeni wa tarakimu 27 53, sawa

Lakini maneno haya yanayotokana ni masharti. Ili kuwafanya nambari halisi katika mifumo maalum ya nambari, unahitaji matokeo ya njia toString(mfumo) badilisha kurudi kwa nambari. Hii haifanyiki tena kwa njia, lakini Nambari ya kazi ya kernel (kitu). Tutazungumza juu ya kazi za kernel katika moja ya masomo yanayokuja, lakini kwa sasa makini na syntax, ni sawa na simu ya kazi:

var a = 1546; var b = a. kwaString(2); var c = Nambari(b);

Au mara moja, "wawili katika moja":

var a = 1546; var b = Nambari(a. kwaString(2 ));

Kumbuka

Ikiwa nambari ya asili imepewa kutofautisha, basi haihitaji kuwekwa kwenye mabano wakati wa kupiga njia toString() .

Sifa za kitu cha Nambari

Tutagusa juu ya mali ya jumla ya kitu cha mjenzi na mfano katika somo kuhusu kitu Kitu, na sasa hebu tugeuke kwenye mali maalum ya kitu Nambari.

Tabia hizi kwa kusoma tu, yaani hatuwezi kuzibadilisha.

MAX_VALUE

Idadi ya juu zaidi inayoweza kuchakatwa katika JavaScript.

Wacha tuone hii ni nambari ya aina gani:

var e = Nambari . MAX_VALUE hati. andika(e)

Matokeo:

1.7976931348623157e+308

Plus katika kesi hii sio ishara ya kuongeza, lakini shahada nzuri, yaani 1.7976931348623157 × 10,308

Kumbuka

Kawaida mimi huonyesha matokeo kwa kutumia maandishi yaliyoandikwa. Lakini hesabu nyingi sana za sehemu zinaweza kupunguza kasi ya upakiaji wa ukurasa, na matokeo mengi katika mafunzo haya yameandikwa kwa mkono, kwa kusema.

MIN_VALUE

Na hii ni ipasavyo thamani ya chini. Hebu tuchunguze.

var f = Nambari . MIN_VALUE hati. andika(f)

Matokeo:

Hiyo ni 5 × 10 -324

Thamani isiyo ya nambari ambayo tayari tumekutana nayo.

Sifa hii inarejeshwa na JavaScript wakati utendakazi wa nambari kwa njia fulani hutoa matokeo yasiyo ya nambari.

NEGATIVE_INFINITY, CHANYA_INFINITY

Hapo zamani za kale walifikiri jambo kama hili: "Kulungu mmoja, kulungu wawili, kulungu wengi."

JavaScript inahesabu kidogo zaidi "advanced": "kulungu mmoja, kulungu wawili, kulungu watatu, ... , 1.7976931348623157 × 10,308 kulungu, kulungu wengi."

Hii "nyingi" ya kupita maumbile inaonyeshwa na mali POSITIVE_INFINITY.

Wakati mchakato unapogeuka, kugawanya kitengo ("kulungu moja") katika vipande vidogo, vidogo, kipande kidogo kilichohesabiwa kitakuwa 5 × 10 -324 sehemu. Chochote kidogo ni tayari NEGATIVE_INFINITY.

Mbinu za kitu cha Nambari

Kumbuka: Kama tu njia ya toString(), njia zingine zote zinahitaji nambari asili kuambatanishwa kwenye mabano ikiwa inawakilishwa wazi (badala ya kutofautisha).

toExponential()

Hurejesha mfuatano unaowakilisha nambari katika nukuu za kisayansi, ikiwa na tarakimu moja kabla ya nukta ya desimali.

Sintaksia:

nambari. kwa Kielelezo(idadi ya ishara)

Hoja idadi ya ishara inabainisha usahihi wa kuzunguka baada ya nukta ya desimali. Ikiwa hoja imeachwa, nambari ya tarakimu baada ya nukta ya desimali ni sawa na nambari inayohitajika kuwakilisha thamani.

Mfano:

var myFullNumber = 4659872156831598853654127 ; hati. andika(MyFullNumber.toExponential(4))

Matokeo:

Iliyorekebishwa ()

Hurejesha mfuatano unaowakilisha nambari ya nukta maalum, iliyozungushwa hadi nambari ya desimali iliyobainishwa katika hoja.

Sintaksia:

nambari. Iliyorekebishwa(idadi ya ishara)

Mifano:

var myDecimal1 = 46.59872156831598853654127 ; var myDecimal2 = 46; hati. andika(myDecimal1.toFixed(1)) hati. andika("
") hati. andika(Decimal2.toFixed(3))

Matokeo:

Njia hii wakati mwingine ni muhimu sana. Kwa mfano, kazi ngumu kutoka kwa somo la mwisho sasa inaweza kuwakilishwa kama hii:

fanya kazi anyRootPlus(x, y) ( var srcnum = Math . exp(Math. logi(x)/y); var matokeo = (srcnum). Iliyorekebishwa(3); matokeo ya kurudi; )

Sasa hebu tuiweke kwenye fomu na tuijaribu:

Kweli, sasa nambari kamili pia zitakuwa na sufuri tatu baada ya nukta. Lakini, kwa kujua tabia ya nambari na kamba, kujua jinsi ya kufanya kazi na waendeshaji wa masharti na ubadilishaji wa aina, sio ngumu sana kutengeneza "kubuni" muhimu ya nambari.

toLocaleString()

Hubadilisha kitu cha nambari kuwa thamani ya mfuatano, kwa kuzingatia mipangilio ya eneo kwa vitenganishi vya desimali na maelfu ya vitenganishi. Sarafu ya kitaifa inachukuliwa kama msingi, kwa hivyo katika toleo la Kirusi nambari zote, hata nambari kamili, zinawasilishwa na sehemu mbili za decimal (kopecks):

var myDrob = 25.327 ; var myMnogo = 25635120 ; var myRoubl = 35; /* ifanye kuwa kubwa zaidi ili kuona koma vyema zaidi */ hati. andika("

" + myDrob. toLocaleString() + "

" ); hati. andika("

" + myMnogo. toLocaleString() + "

" ); hati. andika("

" + myRoubl. toLocaleString() + "

" );

Matokeo:

toPrecision()

Hurejesha mfuatano unaowakilisha nambari iliyo na jumla ya nambari iliyobainishwa ya tarakimu muhimu.

Sintaksia:

nambari. kwa Usahihi(quantityDigits)

Hoja:

quantityDigits idadi ya tarakimu katika mstari ulioonyeshwa. Ikiwa idadi iliyobainishwa ni kubwa kuliko idadi katika nambari asili, sufuri za desimali huonyeshwa.

Hati. andika((354 ).kwa Usahihi(8 ))

Matokeo:

Mbinu toPrecision() Na toLocaleString() pamoja haifanyi kazi, kwa "muundo wa Kirusi" wa nambari za usahihi wowote, utahitaji kuandika kazi yako mwenyewe. Kazi iliyoandikwa inaweza kufanywa njia ya ziada ya kitu Nambari, tayari tumefanya kitu sawa na kitu Tarehe(). Maelezo zaidi katika somo kuhusu kitu Kitu.

toString()

Kweli, tayari tumejadili njia hii kwa undani mwanzoni mwa somo.

Unda mbinu yako mwenyewe

Sasa tutaunda njia ile ile ambayo itaonyesha nambari iliyo na idadi yoyote ya maeneo ya desimali na nafasi kati ya elfu moja na kwa koma kama kitenganishi cha desimali.

Ili kufanya hivyo, tunahitaji kazi ngumu ambayo itabadilisha kamba na safu zilizopatikana kutoka kwa mfano wa kitu. Nambari.

Hebu tutangaze mbinu:

Number.prototype.toRussianString = toRussianString

Kabla ya kuanza kuunda kazi, wacha tuunda kazi.

Kwanza tunahitaji kuwakilisha nambari kama mfuatano na kutoa sehemu kamili, sehemu ya sehemu na sehemu ya kitenganishi kutoka kwayo.

Kisha weka nafasi zinazohitajika katika sehemu kamili, zungusha sehemu ya sehemu hadi idadi ya herufi zinazoweza kubainishwa kama hoja ya chaguo za kukokotoa (na mbinu), na ubadilishe kipindi hadi koma.

Hebu tuanze kazi kwa kutangaza vigezo muhimu.

kazi kwaRussianString(prec) ( /* anuwai za kubadilisha kamba */ var = "" , b = "" , c, d, e;

Kuangalia mbele, nitasema kwamba sehemu ya desimali, kama matokeo ya misukosuko ya kamba, inapoteza kiini chake cha "kipande", na lazima tufanye kazi nayo kama na nambari nyingine kamili. Kufanya kazi nayo tutatumia njia toPrecision(), na hoja ya kazi yetu (na wakati huo huo wa njia yetu) huweka thamani mahsusi kwa njia toPrecision(). Kigezo cha chini cha njia hii ni moja. Na utendakazi wetu pia unaweza kuhitaji sifuri (wakati wa kuzungusha hadi nambari kamili). Na wakati huo huo, kuzungusha kwa usahihi kunapaswa kufanya kazi hata kabla ya kuanza "kutenganisha" kitu. Kwa hivyo, mara moja tunapotangaza vigeu, tutakwepa mtego huu:

/* tofauti inayobadilisha mfano wa kitu kilichopewa kuwa kamba */ ikiwa (prec == 0 ) var str = hii . Iliyorekebishwa(0 ).kwaStringkwaString(10 );

Tunaendelea kutangaza vigezo.

/* kutofautisha kwa thamani ya kurudi */ var nr1; /* vigezo vya sehemu za "mlipuko" */ var intpart, fractpaft, precpart, divider, dot = str. LastIndexOf("." ); /* counter */ var i;

Inaweza kubadilika nukta hupata nafasi ya nukta katika mfuatano wa nambari iliyobainishwa. Kwa nafasi hii tunakata sehemu nzima ( sehemu ya ndani) Ikiwa nambari ni nambari kamili na hakuna uhakika, nafasi yake itakuwa chini ya sifuri. Katika kesi hii, mgawanyiko ( mgawanyiko), na sehemu ya sehemu ( fractpart) lazima ziwe na nyuzi tupu. Vinginevyo, comma imepewa kitenganishi, na sehemu ya sehemu imekatwa kwa kazi zaidi:

ikiwa (dot< 0 ) { intpart = str; fractpart = "" ; mgawanyiko = "" ;) mwingine (intpart = str. kamba ndogo(0, nukta); fractpart = str. kamba ndogo( nukta + 1 , str. urefu); mgawanyiko = "," ;}

Tunafanya kazi na sehemu nzima. Nafasi zinahitajika tu ikiwa kuna zaidi ya herufi 3:

ikiwa ( sehemu. urefu > 3 ) {

Sasa wacha tucheze mchezo ufuatao wa "solitaire" (yote haya hufanyika ndani ya taarifa ya masharti):

Wacha tupitie mara tatu kwa mpangilio wa nyuma.

Kwanza, hebu tuwakusanye katika muundo tofauti a bila nyongeza yoyote, ili tu kuhesabu urefu wa kamba ndogo inayosababisha. Baada ya yote, ikiwa jumla ya nambari haikugawanywa na 3, basi mkia wa nambari 1 au 2 ulibaki upande wa kushoto, na sasa tunaweza kuielezea kama kamba ndogo kwa kutoa urefu wa kamba ndogo na "tatu" kutoka kwa urefu wa kamba nzima (kigeu c) Na kuweka nafasi isiyo ya kuvunja mbele yake (ambayo tutaondoa baadaye). Kwa ajili ya nini? Kwa kuwa vikundi vya tarakimu tatu vilisomwa kwa utaratibu wa nyuma, mkia huu wa awali unapaswa kuwekwa mwishoni mwa safu. Hiyo ni, ikiwa tulikuwa na nambari, sema, 36748521, tunahitaji kupanga safu 521,748 36, kuweka nafasi isiyo ya kuvunja mbele ya kila kikundi ili kuwe na mgawanyiko wa safu (baada ya yote, tunahitaji kupindua. nyuma, na hii inaweza kufanywa kwa kutumia njia ya safu kinyume ()).

Katika maagizo ya mwisho ya kitanzi, tutapanga katika triplets na kuandika matokeo kwa kutofautiana b.

kwa (i=part. urefu-3 ; i>=0 ; i-=3 ) /* kukusanya mapacha watatu */( a = a + intpart. sehemu ndogo(i, 3); /* pata "mkia" wa kushoto */ c = " " + ndani. sehemu ndogo(0, sehemu. urefu-a. urefu); /* weka vitenganishi katika sehemu tatu */ b = b + " " + ndani. sehemu ndogo(i, 3);)

Wakati wa kuongeza kamba b+c tunapata kamba ambayo inahitaji kubadilishwa kuwa safu, na kisha safu hii inabadilishwa na kubadilishwa kuwa kamba (hii yote imeandikwa kwa kutofautisha. d).

D = (b+c). mgawanyiko(" " ).kinyume().kwaString().badala(/,/g, " " );

Safu inabadilishwa kuwa mfuatano pamoja na vitenganishi vya koma hatuvihitaji. Kwa hiyo, katika maagizo sawa tunawaondoa kwa kutumia usemi wa kawaida /,/g, Wapi /,/ kuunda usemi wa kawaida wa koma, na g"bendera", ambayo inaonyesha kuwa unahitaji kubadilisha mifumo yote ya usemi (weka koma zote) zinazoonekana kwenye mstari. Tunazibadilisha na nafasi sawa zisizo za kuvunja.

(Maneno ya kawaida yatajadiliwa kwa kina katika sehemu ya mwisho ya somo.)

Na sasa tunahitaji kusafisha kitu kingine (ndani ya taarifa sawa ya masharti ikiwa (intpart.length> 3)).

Ukweli ni kwamba ama mwanzoni au mwishoni mwa mstari wetu kutakuwa na nafasi ya ziada isiyo ya kuvunja inayojumuisha wahusika 6: "&", "n", "b", "s", "p" na " ;”. Kwa hiyo, hebu tuondoe takataka na kuandika matokeo kwa kutofautiana e:

ikiwa (d. kamba ndogo(0 , 1 ) == "&" e = d. kamba ndogo( 6 , d. urefu-6); mwingine e = d. kamba ndogo(0, d. urefu-6 );

Sasa tunaweza, kwa dhamiri safi, kufunga operator mzima wa masharti na kuandika chaguo mbadala kwa nambari fupi ambayo haihitaji kugawanywa katika "tatu".

) mwingine e = intpart;

Hivyo kutofautiana e huhifadhi sehemu kamili ya nambari, na tutashughulika na sehemu ya desimali.

Makini! Tunapofanya kazi na sehemu ya sehemu (ambayo sasa inahitaji kutibiwa kwa ujumla), lazima tukumbuke wakati huo mapema == 0 kazi itajitahidi, kwa hivyo wacha tuiunganishe mara moja:

ikiwa ( prec != 0 ) (

Sasa unaweza kufanya kazi kwa amani. Lakini kuna "mawe" machache zaidi ambayo sasa tutayapita.

Kwanza, ikiwa tuna sehemu ya sehemu, tuseme 41 , na tunaweka kuzunguka kwa tarakimu 3, kisha njia kwa Usahihi, ikichukua sehemu yetu ya sehemu kama nambari kamili, itatoa matokeo 41.0 , yaani, unahitaji kuondoa uhakika.

Pili, ikiwa sehemu ya sehemu ya nambari ya asili ni zaidi ya nambari 3, basi njia kwa Usahihi itaanza kutoa matokeo katika umbo la kielelezo. Utalazimika kupigana na hii pia.

Kwa hivyo, "tutasafisha" matokeo kupitia anuwai tatu: tayari, precpart1 Na sehemu ya 2.

Precpart = (Nambari (fractpart). kwa Usahihi(kabla)). kwaString(10 )

Sasa "tunasafisha":

/* ikiwa kuna sehemu ya sehemu */ ikiwa (fractpart != "") ( /* tafuta na uondoe uhakika */ precpart1 = precpart. badala(".", "") /* angalia ili kuona kama kuna kielezi hapo, */ var plus = precpart1.lastIndexOf("e"); /* na ikiwa ipo, */ ikiwa (pamoja na> 0) /* vuta nje kwa mizizi, */ precpart2 = precpart1. kamba ndogo(0, pamoja); /* vinginevyo */ mwingine /* usibadilishe chochote */ precpart2 = precpart1 ) /* ikiwa hakuna sehemu ya sehemu, */ mwingine /* kisha tunatoa sifuri na kuondoa tena nukta */ precpart2 = "," +sahihi. badala("." , "" )

Kwa kuwa tulionyesha mwanzoni kwamba ikiwa hakuna sehemu ya sehemu katika nambari ya asili, hakuna comma, basi katika kesi hii tunahitaji kuiweka tena.

) mwingine ( /* yaani, ikiwa prec bado ni sifuri, chapisha tu mistari tupu */ precpart2 = "" ; mgawanyiko = "" ; }

Na wimbo wa mwisho:

Nr1 = e + mgawanyiko + precpart2; kurudi nr1; )

Utendaji mzima:

kazi toRussianString(prec) ( var a = "" , b = "" , c, d, e; ikiwa (prec == 0 ) var str = hii . Iliyorekebishwa(0 ).kwaString(10); else var str = hii . kwaString(10); var nr1; var intpart, fractpaft, precpart, divider, dot = str. LastIndexOf("." ); var i; ikiwa (dot< 0 ) { intpart = str; fractpart = "" ; mgawanyiko = "" ;) mwingine (intpart = str. kamba ndogo(0, nukta); fractpart = str. kamba ndogo( nukta + 1 , str. urefu); mgawanyiko = "," ;) ikiwa (ndani. urefu> 3 ) ( kwa (i=intpart. urefu-3 ; i>=0 ; i-=3 ) ( a = a + intpart. sehemu ndogo(i, 3); c = " " + ndani. sehemu ndogo(0, sehemu. urefu-a. urefu); b = b + " " + ndani. sehemu ndogo(i, 3);) d = (b+c). mgawanyiko(" " ).kinyume().kwaString().badala(/,/g, " " ); ikiwa (d. kamba ndogo(0 , 1 ) == "&" e = d. kamba ndogo( 6 , d. urefu-6); mwingine e = d. kamba ndogo(0, d. urefu-6); ) mwingine e = intpart; ikiwa (prec != 0 ) ( precpart = (Nambari (fractpart). kwa Usahihi(kabla)). kwaString(10) ikiwa (fractpart != "") ( precpart1 = precpart. badala(".", "") var plus = precpart1.lastIndexOf("e"); ikiwa (pamoja na > 0 ) precpart2 = precpart1. kamba ndogo(0, pamoja); else precpart2 = precpart1 ) else precpart2 = "," +sahihi. badala("." , "" )) mwingine ( precpart2 = "" ; mgawanyiko = "" ; ) nr1 = e + mgawanyiko + precpart2; kurudi nr1; )

Kazi hii sasa inaweza kuitwa kama njia.

Var myNumber = 2569843359.6583521 hati. andika(nambari yangu. kwaRussianString(3 ))

Matokeo:

Unaweza kuweka kijenzi cha mbinu na kufanya kazi katika maktaba - yaani, katika faili ya .js ambayo inaweza kuitwa kutoka kwa msimbo wa ukurasa wa wavuti. Unapoandika njia za vitu tofauti, unaweza kupanga njia katika faili za maktaba za vitu hivi na kutumia njia za ziada.