Answers:
යම් සංඛ්යාවක් සඳහා y
සහ සමහර බෙදුම්කරු x
( quotient
) සහ ඉතිරි ( remainder
) ගණනය කරන්නේ:
var quotient = Math.floor(y/x);
var remainder = y % x;
floor
සහ %
ඒ ආකාරයෙන් අනුකූල නොවේ. එක්කෝ trunc
වෙනුවට භාවිතා කරන්න floor
(එමඟින් negative ණ ඉතිරිව ඇති අයට අවසර දීම) හෝ ඉතිරි ( rem = y - div * x
) ලබා ගැනීම සඳහා අඩු කිරීම භාවිතා කරන්න .
rem
කෙසේ හෝ ඉතිරි කොටස ගණනය කිරීමට යන්නේ නම් , ඔබට div
බිම් මහල නොමැතිව වේගයෙන් උපුටා ගැනීම ලබා ගත හැකිය : (y - rem) / x
. 2. ඩොනල්ඩ් නූත්ගේ නිර්දේශිත අර්ථ දැක්වීම අනුව මොඩියුලෝ ක්රියාකාරිත්වය (සං sign ා-ගැලපීම්-බෙදුම්කරු, ඉතිරි කොටස එනම් යුක්ලීඩියානු මාපාංකය හෝ ජාවාස්ක්රිප්ට් සං sign ා-ගැලපුම්-ලාභාංශ නොවේ) යනු අපට ජාවාස්ක්රිප්ට් හි කේත කළ හැකි දෙයකි function mod (a, n) { return a % n + (Math.sign(a) !== Math.sign(n) ? n : 0); }
.
මම බිට්වේස් ක්රියාකරුවන් පිළිබඳ විශේෂ expert යෙක් නොවෙමි, නමුත් සම්පූර්ණ අංකය ලබා ගැනීමට තවත් ක්රමයක් මෙන්න:
var num = ~~(a / b);
මෙය negative ණ සංඛ්යා සඳහාද නිසි ලෙස ක්රියා Math.floor()
කරන අතර වැරදි දිශාවට ගමන් කරයි.
මෙයද නිවැරදි බව පෙනේ:
var num = (a / b) >> 0;
a/b | 0
~~int
, int | 0
සහ int >> 0
ආරම්භක තර්කය වෙනස් නොකරයි, නමුත් පරිවර්තකය ක්රියාකරුට අනිවාර්ය අංගයක් බවට පත් කරන්න.
floor
එහි නම අනුව වැරදි දිශාවකට ගමන් කිරීම කිසිසේත්ම අපහසු නැත - සාමාන්යයෙන් මිනිසුන්ට අවශ්ය දිශාව පමණක් නොවේ!
a = 12447132275286670000; b = 128
Math.floor(a/b)
-> 97243220900677100
සහ ~~(a/b)
-> -1231452688
.
~~(5/2) --> 2
මෙන් (5/2)>>0 --> 2
, නමුත් ~~(5/2) + 1 --> 3
, අතර ~~(5/2)>>0 + 1 --> 1
. ~~
හොඳ තේරීමක් වන්නේ පූර්වාදර්ශය වඩාත් සුදුසු බැවිනි.
මම ෆයර්ෆොක්ස් හි වේග පරීක්ෂණ කිහිපයක් කළා.
-100/3 // -33.33..., 0.3663 millisec
Math.floor(-100/3) // -34, 0.5016 millisec
~~(-100/3) // -33, 0.3619 millisec
(-100/3>>0) // -33, 0.3632 millisec
(-100/3|0) // -33, 0.3856 millisec
(-100-(-100%3))/3 // -33, 0.3591 millisec
/* a=-100, b=3 */
a/b // -33.33..., 0.4863 millisec
Math.floor(a/b) // -34, 0.6019 millisec
~~(a/b) // -33, 0.5148 millisec
(a/b>>0) // -33, 0.5048 millisec
(a/b|0) // -33, 0.5078 millisec
(a-(a%b))/b // -33, 0.6649 millisec
ඉහත දැක්වෙන්නේ එක් එක් අත්හදා බැලීම් මිලියන 10 ක් මත ය.
නිගමනය: භාවිත (a/b>>0)
(හෝ (~~(a/b))
හෝ (a/b|0)
) කාර්යක්ෂමතාව 20% ක් ලාභයක් ගැන සාක්ෂාත් කර ගැනීම. ඒවා සියල්ලම Math.floor
කවදාද, නොගැලපෙන බව මතක තබා ගන්න a/b<0 && a%b!=0
.
Math.floor
හා සිටි-දන්නවා-කෙසේ-කරන්නේද-යන-තවත් බොහෝ API කාර්යයන්, හෝ ඒ ගැන තමා ~
(bitwise-නොවන) සමාගම සහ ආකාරය bitwise මෙහෙයුම් JS වැඩ හා පසුව තේරුම් ද්විත්ව tilde බලපෑම?
Math.floor
වඩාත් හොඳින් තේරුම් ගනු ඇත. එසේ නොවුවද, මෙය ගූගල් කළ හැකි ය.
ES6 නව Math.trunc
ක්රමය හඳුන්වා දෙයි . Negative ණ සංඛ්යා සඳහාද එය ක්රියාත්මක කිරීම සඳහා @ මාර්ක් එලියට්ගේ පිළිතුර නිවැරදි කිරීමට මෙය ඉඩ දෙයි :
var div = Math.trunc(y/x);
var rem = y % x;
Math
2 31 ට වැඩි අංක සමඟ වැඩ කරන බිට්වේස් ක්රියාකරුවන්ට වඩා ක්රමවලට වාසි ඇති බව සලකන්න .
18014398509481984 == 18014398509481985
.
~~(x/y)
. අත්සන් කළ බිටු 54 ක් දක්වා විශාල සංඛ්යාවක් සඳහා සහය දැක්විය යුතුද? Math.trunc
ඔබ සතුව ඇත්නම් හෝ Math.floor
වෙනත් ආකාරයකින් භාවිතා කරන්න (negative ණ සංඛ්යා සඳහා නිවැරදි කරන්න). ඊටත් වඩා විශාල සංඛ්යා සඳහා සහය දැක්විය යුතුද? විශාල සංඛ්යා පුස්තකාලයක් භාවිතා කරන්න.
divmod
ඔබට මෙය ක්රියාත්මක කළ හැකිය:function divmod(x, y) { var div = Math.trunc(x/y); var rem = x % y; return [div, rem]; }
var remainder = x % y;
return (x - remainder) / y;
Math.trunc
:). මම 100,3 සමඟ පරීක්ෂා කළෙමි; -100,3; 100, -3 සහ -100, -3. ඇත්ත වශයෙන්ම, ඔබේ අදහස සහ දේවල් වෙනස් වීමෙන් බොහෝ කාලයක් ගත වී ඇත.
මම සාමාන්යයෙන් භාවිතා කරන්නේ:
const quotient = (a - a % b) / b;
const remainder = a % b;
එය බොහෝ විට වඩාත්ම අලංකාර නොවේ, නමුත් එය ක්රියා කරයි.
parseInt
කප්පාදු කළ ප්රති .ලයක් ලබා ගැනීම සඳහා ඔබට ශ්රිතය භාවිතා කළ හැකිය .
parseInt(a/b)
ඉතිරියක් ලබා ගැනීම සඳහා, මෝඩ් ක්රියාකරු භාවිතා කරන්න:
a%b
10 වන පාදම සමඟ රේඩික්ස් පරාමිතිය භාවිතා නොකිරීමට parseInt හි නූල් සහිත අන්තරායන් ඇත
parseInt("09", 10)
සමහර අවස්ථා වලදී සංඛ්යා වල නූල් නිරූපණය විද්යාත්මක අංකනයක් විය හැකිය, මේ අවස්ථාවේ දී, parseInt වැරදි ප්රති .ලයක් ලබා දෙනු ඇත.
parseInt(100000000000000000000000000000000, 10) // 1e+32
මෙම ඇමතුම ප්රති 1 ලයක් ලෙස 1 ක් නිපදවනු ඇත.
parseInt
හැකි විට වළක්වා ගත යුතුය. මෙන්න ඩග්ලස් ක්රොක්ෆර්ඩ්ගේ අනතුරු ඇඟවීම: “නූලෙහි පළමු අක්ෂරය 0 නම්, 10 වන පාදම වෙනුවට 8 වන පාදයේ නූල ඇගයීමට ලක් කෙරේ. පාදම 8, 8 සහ 9 ඉලක්කම් නොවේ, එබැවින් parseInt (" 08 ") සහ parseInt ("09") ඒවායේ ප්රති result ලයක් ලෙස 0 නිපදවයි.මෙම දෝෂය දිනයන් සහ වේලාවන් විග්රහ කරන වැඩසටහන් වල ගැටළු ඇති කරයි. වාසනාවකට මෙන්, parseInt හට රේඩික්ස් පරාමිතියක් ගත හැකි අතර එමඟින් parseInt ("08", 10) 8 නිපදවයි. රේඩික්ස් පරාමිතිය සපයන්න. ” archive.oreilly.com/pub/a/javascript/excerpts/…
parseInt
වැළකී සිටිය යුතු යැයි ඔහු නොකියයි ; දැනුවත්ව සිටිය යුතු කරුණු කිහිපයක් තිබේ. ඔබ මේ දේවල් පිළිබඳව දැනුවත් විය යුතු අතර ඒවාට මුහුණ දීමට සූදානම් විය යුතුය.
parseInt
අංක තර්කයක් සමඟ කිසි විටෙකත් අමතන්න . parseInt
අර්ධ වශයෙන් සංඛ්යාත්මක නූල් විග්රහ කළ යුතු අතර සංඛ්යා කප්පාදු නොකරයි.
ජාවාස්ක්රිප්ට් ගණිතමය අර්ථ දැක්වීම් අනුගමනය කරමින් negative ණ සංඛ්යා වල තට්ටුව සහ පූර්ණ සංඛ්යා නොවන සංඛ්යා ගණනය කරයි.
FLOOR යන්න අර්ථ දැක්වෙන්නේ "පරාමිතියට වඩා කුඩා විශාලතම සංඛ්යා අංකය" ලෙස ය:
REMAINDER යන්න අර්ථ දැක්වෙන්නේ බෙදීමක (ඉතිරිව ඇති) (යුක්ලීඩියානු අංක ගණිතය) ලෙසිනි. ලාභාංශ පූර්ණ සංඛ්යාවක් නොවන විට, උපුටා ගැනීම සාමාන්යයෙන් පූර්ණ සංඛ්යාවක් නොවේ, එනම් ඉතිරියක් නොමැත, නමුත් සංඛ්යාංකය පූර්ණ සංඛ්යාවක් වීමට බල කරන්නේ නම් (සහ යමෙකු a හි ඉතිරි හෝ මාපාංකය ලබා ගැනීමට උත්සාහ කළ විට සිදු වන්නේ එයයි පාවෙන ලක්ෂ්ය අංකය), පූර්ණ සංඛ්යාවක් නොවන “ඉතුරු” වනු ඇත, පැහැදිලිවම.
ජාවාස්ක්රිප්ට් සෑම දෙයක්ම ගණනය කළ පරිදි ගණනය කරයි, එබැවින් ක්රමලේඛකයා නිසි ප්රශ්න ඇසීමට ප්රවේශම් විය යුතුය (සහ මිනිසුන් අසන දෙයට පිළිතුරු දීමට සැලකිලිමත් විය යුතුය!) යරින්ගේ පළමු ප්රශ්නය වූයේ “X හි Y හි පූර්ණ සංඛ්යා බෙදීම කුමක්ද” යන්න නොවේ, නමුත්, ඒ වෙනුවට, "ලබා දී ඇති පූර්ණ සංඛ්යාවක් තවත් ගණනකට යන වාර ගණන". ධනාත්මක සංඛ්යා සඳහා, පිළිතුර දෙකටම එක හා සමාන වේ, නමුත් negative ණ සංඛ්යා සඳහා නොවේ, මන්ද පූර්ණ සංඛ්යා බෙදීම (බෙදුම්කරුගේ ලාභාංශ) අංකයක් (බෙදුම්කරු) තවත් (ලාභාංශයකට) යන වාරයට වඩා -1 කුඩා වනු ඇත. වෙනත් වචන වලින් කිවහොත්, FLOOR negative ණ සංඛ්යාවක පූර්ණ සංඛ්යා බෙදීම සඳහා නිවැරදි පිළිතුර ලබා දෙනු ඇත, නමුත් යරින් එය විමසුවේ නැත!
ගැමාක්ස් නිවැරදිව පිළිතුරු දුන් අතර, එම කේතය යාරින් ඇසූ පරිදි ක්රියා කරයි. අනෙක් අතට, සැමුවෙල් වැරදියි, ඔහු ගණිතය කළේ නැත, මම අනුමාන කරමි, නැතහොත් එය ක්රියාත්මක වන බව ඔහු දැක ඇත (එසේම, ඔහුගේ ආදර්ශයේ බෙදුම්කරු කුමක්දැයි ඔහු නොකියයි, නමුත් මම විශ්වාස කරමි 3):
ඉතිරි = X% Y = -100% 3 = -1
GoesInto = (X - Remainder) / Y = (-100 - -1) / 3 = -99 / 3 = -33
මාර්ගය වන විට, මම ෆයර්ෆොක්ස් 27.0.1 හි කේතය පරීක්ෂා කළෙමි, එය අපේක්ෂිත පරිදි ධනාත්මක හා negative ණ සංඛ්යා සමඟ මෙන්ම ලාභාංශ සහ බෙදුම්කරු සඳහා පූර්ණ සංඛ්යා නොවන අගයන් සමඟ ක්රියා කළේය. උදාහරණයක්:
-100.34 / 3.57: GoesInto = -28, Remainder = -0.3800000000000079
ඔව්, මම දුටුවා, එහි නිරවද්යතා ගැටලුවක් ඇති නමුත් එය පරීක්ෂා කිරීමට මට වෙලාවක් නොතිබුණි (එය ෆයර්ෆොක්ස්, වින්ඩෝස් 7 හෝ මගේ CPU හි FPU සමඟ ගැටළුවක් දැයි මම නොදනිමි). යරින්ගේ ප්රශ්නයට, පූර්ණ සංඛ්යා පමණක් ඇතුළත් වන ගැමාක්ස් කේතය පරිපූර්ණව ක්රියාත්මක වේ.
ඇලෙක්ස් මුවර්-නියෙමිගේ ප්රකාශය පිළිතුරක් ලෙස:
ගූගල් වෙතින් රුබීවාදීන් සෙවීම සඳහා divmod
, ඔබට එය ක්රියාත්මක කළ හැකිය:
function divmod(x, y) {
var div = Math.trunc(x/y);
var rem = x % y;
return [div, rem];
}
ප්රති ult ලය:
// [2, 33]
divmod
පොළව බෙදීම ( Math.floor
) භාවිතා කරයි , එය Math.trunc
negative ණ සංඛ්යා සම්බන්ධ වන විට කප්පාදු කළ බෙදීම් ( ) ට වඩා වෙනස් වේ . එන්පීඑම් divmod
පැකේජය , රූබිdivmod
, එස්ඩබ්ලිව්අයි-ප්රොලොග්divmod
සහ තවත් බොහෝ ක්රියාත්මක කිරීම් සඳහාද මෙයම වේ .
divmod
පවතින බව සලකන්න, එය මෙහෙයුම් දෙක වෙන වෙනම ගණනය කිරීම මෙන් දෙගුණයක් වේගයෙන් සිදු කරයි. මෙම කාර්යසාධන ප්රතිලාභ නොමැතිව එවැනි කාර්යයක් සැපයීම ව්යාකූල විය හැකිය.
ඔබ දෙදෙනෙකුගේ බලයන් සමඟ බෙදී යන්නේ නම්, ඔබට බිට්වේස් ක්රියාකරුවන් භාවිතා කළ හැකිය:
export function divideBy2(num) {
return [num >> 1, num & 1];
}
export function divideBy4(num) {
return [num >> 2, num & 3];
}
export function divideBy8(num) {
return [num >> 3, num & 7];
}
(පළමුවැන්න නම්, දෙවැන්න ඉතිරිය)
function divideByPowerOf2(num, exponent) { return [num >> exponent, num & ((1 << exponent) - 1)]; }
.
පිටු ගණන ගණනය කිරීම එක් පියවරකින් කළ හැකිය: Math.ceil (x / y)
ධනාත්මක හා සෘණ පූර්ණ සංඛ්යා අගයන් හැසිරවිය යුතු ආකාරය තීරණය කිරීමට ඔබට ත්රිකෝණය භාවිතා කළ හැකිය.
var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1
අංකය ධනාත්මක නම්, සියල්ල හොඳයි. අංකය negative ණ නම්, Math.floor නිෂේධාත්මකව හැසිරෙන ආකාරය නිසා එය 1 ක් එකතු වේ.
මෙය සැමවිටම ශුන්ය දෙසට කපා දමනු ඇත. එය ප්රමාදදැයි විශ්වාස නැත, නමුත් මෙන්න එය යන්නේ:
function intdiv(dividend, divisor) {
divisor = divisor - divisor % 1;
if (divisor == 0) throw new Error("division by zero");
dividend = dividend - dividend % 1;
var rem = dividend % divisor;
return {
remainder: rem,
quotient: (dividend - rem) / divisor
};
}
ජේඑස් ධාවන කාලයට නිරූපණය කළ නොහැකි ඉතා විශාල සංඛ්යා සඳහා ඉතිරි කොටස ගණනය කිරීමට ඔබට අවශ්ය නම් (2 ^ 32 ට වඩා වැඩි පූර්ණ සංඛ්යාවක් පාවෙන ලෙස නිරූපණය වන අතර එමඟින් නිරවද්යතාවය නැති වේ), ඔබ යම් උපක්රමයක් කළ යුතුය.
අපගේ දෛනික ජීවිතයේ බොහෝ අවස්ථාවන්හි (බැංකු ගිණුම් අංක, ක්රෙඩිට් කාඩ්, ...) ඇති බොහෝ චෙක්පත් සංඛ්යා පරික්ෂා කිරීම සඳහා මෙය විශේෂයෙන් වැදගත් වේ.
පළමුවෙන්ම ඔබට ඔබේ අංකය නූලක් ලෙස අවශ්ය වේ (එසේ නොමැතිනම් ඔබට දැනටමත් නිරවද්යතාවය නැති වී ඇති අතර ඉතිරිය තේරුමක් නැත).
str = '123456789123456789123456789'
ඔබට දැන් ඔබේ නූල කුඩා කොටස් වලට බෙදිය යුතුය, ප්රමාණවත් තරම් කුඩා බැවින් ඕනෑම ඉතිරියක් හා නූල් කැබැල්ලක් සංක්ෂිප්තව ඉලක්කම් 9 කට ගැලපේ.
digits = 9 - String(divisor).length
නූල බෙදීමට නිත්ය ප්රකාශනයක් සකස් කරන්න
splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g')
උදාහරණයක් ලෙස, digits
7 නම් , regexp වේ
/.{1,7}(?=(.{7})+$)/g
එය උපරිම දිග 7 ක නොබැඳි උපස්ථරයකට ගැලපේ, එය අනුගමනය කරනුයේ ( (?=...)
ධනාත්මක බැල්මකි) 7 න් ගුණ කළ හැකි අක්ෂර ගණනාවකි.
දැන් සෑම කොටසක්ම පූර්ණ සංඛ්යාවක් බවට පරිවර්තනය කර ඉතිරි කොටස් ගණනය කරන්න reduce
(පෙර ඉතිරි කොටස නැවත එකතු කිරීම - හෝ 0 - නිවැරදි බලයෙන් 10 න් ගුණ කිරීම):
reducer = (rem, piece) => (rem * Math.pow(10, digits) + piece) % divisor
"අඩු කිරීම" ඉතිරි ඇල්ගොරිතම නිසා මෙය ක්රියාත්මක වේ:
n mod d = (n - kd) mod d
එමඟින් සංඛ්යාවක දශම නිරූපණයෙහි ඕනෑම 'ආරම්භක කොටසක්' එහි ඉතිරි කොටස සමඟ ප්රතිස්ථාපනය කිරීමට ඉඩ සලසයි.
අවසාන කේතය මෙසේ වනු ඇත:
function remainder(num, div) {
const digits = 9 - String(div).length;
const splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g');
const mult = Math.pow(10, digits);
const reducer = (rem, piece) => (rem * mult + piece) % div;
return str.match(splitter).map(Number).reduce(reducer, 0);
}
3.5 % 2
1.5 දක්වා තක්සේරු කරයි. අවශ්ය පරිදි හැසිරවීමට වග බලා ගන්න (parseInt, floor, etc.)