Bitwise Operation និង Flag
មាតិកា
- ហេតុអ្វីត្រូវធ្វើការជាមួយ Bit នីមួយៗ?
- AND, OR, XOR និង NOT
- Shift
- Bitmask៖ ខ្ចប់តម្លៃបាទ/ចាសជាច្រើនចូលក្នុងលេខតែមួយ
- សិទ្ធិ Unix និង chmod 755
- Feature Flag
- ល្បិច Bit ដែលមានប្រយោជន៍
- ការប្រុងប្រយ័ត្ន 32-Bit ក្នុង JavaScript
- រូបមន្ត៖ bits.js
- សាកល្បងដោយខ្លួនឯង
1. ហេតុអ្វីត្រូវធ្វើការជាមួយ Bit នីមួយៗ?
ក្នុងជំពូកមុន អ្នកបានឃើញថាលេខគឺជាជួរនៃ bit។ ពេលខ្លះវាមានប្រយោជន៍ក្នុងការចាត់ទុកជួរនោះជា កុងតាក់ដាច់ដោយឡែកជាច្រើន ជំនួសឲ្យបរិមាណតែមួយ។
ស្រមៃថាអ្នកប្រើក្នុង app មួយអាចមានសិទ្ធិទាំងនេះ៖ read, write, delete, share, export, admin។ អ្នកអាចបន្ថែម column true/false ប្រាំមួយទៅ database។ ឬអ្នកអាចប្រើ លេខតែមួយ ដែល bit នីមួយៗជាសិទ្ធិមួយ។ វាតូចជាង ចម្លងងាយ និងពិនិត្យលឿន។ ប្រព័ន្ធឯកសារ ពិធីការបណ្តាញ បណ្ណាល័យក្រាហ្វិក និង game engine សុទ្ធតែធ្វើបែបនេះ។
ដើម្បីធ្វើវា អ្នកត្រូវការ bitwise operator៖ operator ដែលធ្វើការលើ bit នីមួយៗនៃលេខដាច់ដោយឡែកពីគ្នា។
2. AND, OR, XOR និង NOT
Operator នីមួយៗប្រៀបធៀប bit របស់លេខពីរតាមទីតាំងម្តងមួយៗ។ យើងនឹងប្រើ 12 (1100) និង 10 (1010)។
| Operator | ឈ្មោះ | ច្បាប់សម្រាប់ទីតាំង bit នីមួយៗ | ឧទាហរណ៍ |
|---|---|---|---|
& | AND | 1 តែនៅពេល ទាំងពីរ bit ជា 1 | 12 & 10 គឺ 8 |
| | OR | 1 បើ យ៉ាងហោចណាស់មួយ bit ជា 1 | 12 | 10 គឺ 14 |
^ | XOR | 1 បើ bit ខុសគ្នា | 12 ^ 10 គឺ 6 |
~ | NOT | បត់គ្រប់ bit (input មួយ) | ~12 គឺ -13 |
តម្រឹមពួកវាដើម្បីមើលឃើញ៖
1100 (12) 1100 (12) 1100 (12)
& 1010 (10) | 1010 (10) ^ 1010 (10)
---- ---- ----
1000 (8) 1110 (14) 0110 (6)
ក្នុងកូដ៖
console.log(0b1100 & 0b1010); // 8
console.log(0b1100 | 0b1010); // 14
console.log(0b1100 ^ 0b1010); // 6
នេះជារបៀបចងចាំពួកវា៖
- AND គឺជាតម្រង៖ វារក្សាតែ bit ដែលបើកទាំងពីរ។ វាត្រូវបានប្រើដើម្បី ពិនិត្យ និង សម្អាត (clear) bit។
- OR គឺជាការបញ្ចូលគ្នា៖ វាបើក bit។ វាត្រូវបានប្រើដើម្បី កំណត់ (set) bit។
- XOR គឺជាឧបករណ៍រកភាពខុសគ្នា៖ វាបត់ bit កន្លែងដែលម្ខាងទៀតមាន
1។ វាត្រូវបានប្រើដើម្បី បិទបើក (toggle) bit។
~ (NOT) បត់គ្រប់ bit។ លទ្ធផលមើលទៅចម្លែក ព្រោះ JavaScript ធ្វើការជាមួយលេខ 32-bit មានសញ្ញា ដូច្នេះការបត់ 12 ផ្តល់ -13។ ច្បាប់ងាយមួយគឺ ~n ស្មើនឹង -n - 1។ ដើម្បីមើលតែ bit ខាងក្រោម សូមផ្សំវាជាមួយ AND៖
console.log(~12); // -13
console.log(~0b1100 & 0b1111); // 3 (0011: bit ទាំងបួនត្រូវបានបត់)
សម្រាប់ flag អ្នកភាគច្រើនប្រើ ~ ជាមួយ & ដើម្បី clear bit ដូច្នេះអ្នកកម្របានមើលលទ្ធផលអវិជ្ជមានដើមទេ។
3. Shift
Shift រុញ bit ទាំងអស់ទៅឆ្វេង ឬស្តាំ។
| Operator | អត្ថន័យ | ឧទាហរណ៍ | លទ្ធផល |
|---|---|---|---|
<< | Shift ឆ្វេង | 3 << 2 | 12 |
>> | Shift ស្តាំ | 12 >> 2 | 3 |
0011 << 2 = 1100 (3 becomes 12)
1100 >> 2 = 0011 (12 becomes 3)
ការ shift ឆ្វេង 1 ទ្វេដង លេខ ហើយការ shift ឆ្វេង n គុណនឹង 2^n។ ការ shift ស្តាំ n ចែកនឹង 2^n ហើយបោះបង់សំណល់ (វាបង្គត់ឆ្ពោះទៅអនន្តអវិជ្ជមាន)៖
console.log(3 << 2); // 12 (ដូច 3 * 4)
console.log(1 << 10); // 1024 (ដូច 2 ** 10)
console.log(12 >> 2); // 3 (ដូច Math.floor(12 / 4))
console.log(13 >> 1); // 6 (13 / 2 គឺ 6.5, .5 ត្រូវបានបោះបង់)
Shift 1 << n មានប្រយោជន៍ជាពិសេស។ វាបង្កើតលេខដែលមាន តែ bit n ប៉ុណ្ណោះដែលបើក រាប់ចាប់ពីសូន្យនៅខាងស្តាំ៖
| Expression | Binary | តម្លៃ |
|---|---|---|
1 << 0 | 0001 | 1 |
1 << 1 | 0010 | 2 |
1 << 2 | 0100 | 4 |
1 << 3 | 1000 | 8 |
នោះផ្តល់ឲ្យយើងនូវប្លុកសំណង់សម្រាប់ flag។
ក៏មាន >>> ដែរ គឺ shift ស្តាំគ្មានសញ្ញា (unsigned)។ យើងនឹងជួបវាក្នុងផ្នែក 32-bit។
4. Bitmask៖ ខ្ចប់តម្លៃបាទ/ចាសជាច្រើនចូលក្នុងលេខតែមួយ
Flag គឺជាលេខដែលមាន bit តែមួយបើកយ៉ាងពិតប្រាកដ។ Bitmask គឺជាលេខដែលប្រើដើម្បីជ្រើសរើស ឬផ្លាស់ប្តូរ bit ជាក់លាក់។ តោះផ្តល់ឲ្យសិទ្ធិនីមួយៗមាន bit ផ្ទាល់ខ្លួន៖
const READ = 0b100; // 4
const WRITE = 0b010; // 2
const EXEC = 0b001; // 1
សិទ្ធិរបស់អ្នកប្រើគឺជាលេខតែមួយដែលផ្សំ flag ដោយ OR៖
let perms = READ | WRITE;
console.log(perms); // 6
console.log(perms.toString(2)); // 110
ឥឡូវនេះជាប្រតិបត្តិការទាំងបួនដែលគ្របដណ្តប់ស្ទើរតែគ្រប់ការប្រើប្រាស់៖
| ការងារ | Expression | ហេតុអ្វីវាដំណើរការ |
|---|---|---|
| ពិនិត្យ flag | (perms & FLAG) === FLAG | AND រក្សា bit របស់ flag តែនៅពេលវាបើក |
| កំណត់ flag | perms | FLAG | OR បើក bit ហើយទុក bit ផ្សេងទៀតតាមដើម |
| សម្អាត flag | perms & ~FLAG | ~FLAG គឺជាមួយទាំងអស់លើកលែង bit នោះ; AND លុបវាចេញ |
| បិទបើក flag | perms ^ FLAG | XOR បត់តែ bit នោះ |
console.log((perms & WRITE) === WRITE); // true
console.log((perms & EXEC) === EXEC); // false
perms = perms | EXEC; // កំណត់ EXEC -> 111 = 7
perms = perms & ~WRITE; // សម្អាត WRITE -> 101 = 5
perms = perms ^ WRITE; // បិទបើក WRITE -> 111 = 7
ហេតុអ្វីប្រៀបធៀបជាមួយ === FLAG ហើយមិនត្រឹមតែសាកថាមិនមែនសូន្យ? នៅពេលអ្នកពិនិត្យ flag ច្រើនក្នុងពេលតែមួយ ដូចជា READ | WRITE អ្នកត្រូវដឹងថា ទាំងអស់ បានបើក។ ការប្រៀបធៀបនឹង mask ទាំងមូលធ្វើបែបនោះ។
5. សិទ្ធិ Unix និង chmod 755
Linux និង macOS រក្សាទុកសិទ្ធិឯកសារដោយវិធីនេះយ៉ាងពិតប្រាកដ។ ឯកសារនីមួយៗមានបីក្រុមនៃ flag បី៖
| ក្រុម | អ្នកណា |
|---|---|
| Owner (user) | អ្នកដែលជាម្ចាស់ឯកសារ |
| Group | អ្នកប្រើក្នុង group របស់ឯកសារ |
| Other | អ្នកផ្សេងទៀតទាំងអស់ |
ក្រុមនីមួយៗមាន read (r = 4), write (w = 2) និង execute (x = 1)។ បូកលេខដើម្បីទទួលបានខ្ទង់មួយពី 0 ដល់ 7៖
| ខ្ទង់ | Binary | សិទ្ធិ |
|---|---|---|
| 7 | 111 | rwx |
| 6 | 110 | rw- |
| 5 | 101 | r-x |
| 4 | 100 | r-- |
| 0 | 000 | --- |
បីខ្ទង់បង្កើតបាន mode ទាំងមូល ដែលជាមូលហេតុដែលអ្នកសរសេរ chmod 755៖
chmod 755 deploy.sh # owner: rwx, group: r-x, other: r-x
ls -l deploy.sh
# -rwxr-xr-x 1 dara staff 120 Oct 3 09:00 deploy.sh
7 គឺ rwx សម្រាប់ owner, 5 ទីមួយគឺ r-x សម្រាប់ group ហើយ 5 ចុងក្រោយគឺ r-x សម្រាប់អ្នកផ្សេងទៀតទាំងអស់។ Mode ធម្មតា៖
| Mode | អត្ថន័យ | ការប្រើប្រាស់ធម្មតា |
|---|---|---|
755 | rwxr-xr-x | កម្មវិធី, script, ថត |
644 | rw-r--r-- | ឯកសារធម្មតា, ទំព័រ web |
600 | rw------- | private key, ការសម្ងាត់ |
នេះជាមូលហេតុដែល octal មានប្រយោជន៍៖ ខ្ទង់ octal មួយគឺបី bit យ៉ាងពិតប្រាកដ ដូច្នេះ 0o755 គឺ 111 101 101 ក្នុង binary។ ក្នុង JavaScript អ្នកអាចសរសេរវាដោយផ្ទាល់ ហើយទាញក្រុមនីមួយៗចេញដោយ shift និង mask៖
const mode = 0o755;
console.log(mode); // 493
console.log(mode.toString(2)); // 111101101
console.log((mode >> 6) & 0b111); // 7 (owner)
console.log((mode >> 3) & 0b111); // 5 (group)
console.log(mode & 0b111); // 5 (other)
បន្ទាត់នីមួយៗ shift ក្រុមដែលអ្នកចង់បានចុះមកបី bit ទាបបំផុត បន្ទាប់មកប្រើ & 0b111 ដើម្បីកាត់អ្វីៗផ្សេងទៀតចេញ។ យើងបំប្លែងរឿងនេះទៅជា function toUnixMode ក្នុងរូបមន្ត។
6. Feature Flag
គំនិតដូចគ្នាដំណើរការសម្រាប់ការកំណត់ app។ ឧបមាថាផលិតផលរបស់អ្នកមាន feature ស្រេចចិត្តបួន ហើយអ្នករក្សាទុកវាក្នុងលេខមួយក្នុងមួយអ្នកប្រើ៖
const Feature = {
DARK_MODE: 1 << 0, // 1
BETA: 1 << 1, // 2
EXPORT: 1 << 2, // 4
ADMIN: 1 << 3, // 8
};
ការប្រើ 1 << n មានន័យថាអ្នកត្រូវរាប់តែទីតាំង មិនចាំបាច់គណនាស្វ័យគុណនៃពីរក្នុងក្បាលទេ ហើយវាធ្វើឲ្យពិបាកនឹងផ្តល់ bit ដូចគ្នាដល់ flag ពីរដោយចៃដន្យ។
let user = Feature.DARK_MODE | Feature.ADMIN;
console.log(user); // 9
console.log(user.toString(2).padStart(4, "0")); // 1001
console.log((user & Feature.BETA) === Feature.BETA); // false
console.log((user & Feature.ADMIN) === Feature.ADMIN); // true
user = user | Feature.BETA; // 1011
user = user & ~Feature.DARK_MODE; // 1010
console.log(user); // 10
លេខតែមួយរក្សាទុកការកំណត់ទាំងបួន។ Column integer ក្នុង database ផ្ទុកបានរហូតដល់ 31 ឬ 32 flag។ អ្នកអាចប្រៀបធៀប ចម្លង និងផ្ញើលេខនោះដោយមិនចាំបាច់ parse។
ការដោះដូរដោយស្មោះត្រង់៖ លេខដូចជា 10 មិនអាចអានបានដោយខ្លួនឯងទេ ហើយការបន្ថែម flag ទី 33 មិនអាចទៅរួចក្នុង column 32-bit ធម្មតា។ សម្រាប់ការកំណត់ដែលមនុស្សអាន និងកែសម្រួលញឹកញាប់ array ដូចជា ["beta", "admin"] ឬបញ្ជី boolean គឺច្បាស់ជាង។ ប្រើ bit flag នៅពេលដែលទំហំ ល្បឿន ឬទម្រង់ដែលមានស្រាប់ (ដូចជា mode របស់ Unix ឬពិធីការ binary) សំខាន់។ ជំពូក
5 បង្ហាញថា លេខ flag និងសំណុំនៃឈ្មោះគឺជាទស្សនៈពីរនៃគំនិតតែមួយ។
7. ល្បិច Bit ដែលមានប្រយោជន៍
នៅពេលអ្នកអាន bit បានស្រួល expression ខ្លីៗខ្លះក្លាយជាច្បាស់៖
function isOdd(n) {
return (n & 1) === 1; // bit ទាបបំផុតគឺ 1 សម្រាប់លេខសេស
}
console.log(isOdd(7)); // true
console.log(isOdd(10)); // false
function isPowerOfTwo(n) {
return n > 0 && (n & (n - 1)) === 0;
}
console.log(isPowerOfTwo(64)); // true
console.log(isPowerOfTwo(96)); // false
ហេតុអ្វីការពិនិត្យស្វ័យគុណនៃពីរដំណើរការ? ស្វ័យគុណនៃពីរមាន bit តែមួយបើកយ៉ាងពិតប្រាកដ ដូចជា 1000000 (64)។ ការដក 1 ផ្តល់ 0111111 (63) ដែលគ្រប់ bit ខុសគ្នា ដូច្នេះ 64 & 63 គឺ 0។ សម្រាប់ 96 (1100000) bit ខាងលើនៅរស់ ដូច្នេះលទ្ធផលមិនមែនសូន្យទេ។
ល្បិចមួយទៀតគឺ XOR ជាមួយតម្លៃដូចគ្នាពីរដង ដែលនាំអ្នកត្រឡប់ទៅចំណុចចាប់ផ្តើមវិញ៖ 7 ^ 2 ^ 2 គឺ 7។ល្បែងផ្គុំរូបអំពីការអ៊ិនគ្រីបសាមញ្ញ checksum និងក្បួនដោះដូរតម្លៃប្រើវា ទោះបីជាក្នុងកូដប្រចាំថ្ងៃអ្នកកម្រត្រូវការវាក៏ដោយ។
ត្រូវអានបានស្រួលជាមុនសិន។ n % 2 === 0 ច្បាស់ជាង (n & 1) === 0 ក្នុងកូដភាគច្រើន។ ល្បិច bit មានតម្លៃនៅពេលអ្នកធ្វើការជាមួយ flag និងទិន្នន័យ binary មិនមែននៅពេលអ្នកគ្រាន់តែព្យាយាមធ្វើឲ្យខ្លួនមើលទៅឆ្លាតនោះទេ។
8. ការប្រុងប្រយ័ត្ន 32-Bit ក្នុង JavaScript
លេខ JavaScript ធម្មតាគឺជាតម្លៃ floating-point 64-bit ដូចដែលអ្នកបានឃើញក្នុងជំពូកទី 2។ ប៉ុន្តែ bitwise operator ធ្វើការលើ integer 32-bit មានសញ្ញា។ មុនប្រតិបត្តិការ JavaScript បំប្លែងលេខរបស់អ្នកទៅ 32 bit ហើយបំប្លែងលទ្ធផលត្រឡប់មកវិញ។ នេះបណ្តាលឲ្យមានការភ្ញាក់ផ្អើលជាមួយលេខធំ៖
console.log(2 ** 31); // 2147483648
console.log(2 ** 31 | 0); // -2147483648 (រុំជុំទៅអវិជ្ជមាន)
console.log(1 << 31); // -2147483648
console.log(1 << 32); // 1 (ចំនួន shift រុំជុំ: 32 ដើរតួជា 0)
console.log(2 ** 32 + 5 | 0); // 5 (bit ខាងលើត្រូវបានកាត់ចេញ)
console.log(5.9 | 0); // 5 (ទសភាគត្រូវបានបោះបង់)
ច្បាប់បីដែលត្រូវយកទៅ៖
- មានតែ 32 bit។ Flag លើសពី bit 30 គឺមានហានិភ័យ។ Bit 31 គឺ bit សញ្ញា ហើយធ្វើឲ្យលេខអវិជ្ជមាន។ រក្សា flag ត្រឹម
1 << 30ឬទាបជាងនេះ ឬយ៉ាងច្រើន 31 flag។ - លទ្ធផលអាចអវិជ្ជមាន។
1 << 31គឺ-2147483648។ ប្រើ>>> 0ដើម្បីអានលទ្ធផលជាលេខគ្មានសញ្ញា (មិនដែលអវិជ្ជមាន)៖
console.log((1 << 31) >>> 0); // 2147483648
console.log(-1 >>> 0); // 4294967295
console.log(~5 >>> 0); // 4294967290
- ត្រូវការ flag លើសពី 32? ប្រើ
BigIntដែល operator&,|,^,<<ធ្វើការលើលេខទំហំណាក៏បាន។ សរសេរ literal របស់ BigInt ដោយមានnនៅខាងចុង៖
console.log(1n << 40n); // 1099511627776n
console.log(5n & 3n); // 1n
អ្នកមិនអាចលាយ BigInt និងលេខធម្មតាក្នុង expression តែមួយបានទេ ដូចជា 1n | 2 ដូច្នេះត្រូវជ្រើសរើសប្រភេទមួយសម្រាប់សំណុំ flag នីមួយៗ។ ជំពូក
7
គ្របដណ្តប់ BigInt ឲ្យបានត្រឹមត្រូវ។
ទម្លាប់មួយទៀតដែលគួរមាន៖ x | 0 និង ~~x ពេលខ្លះត្រូវបានប្រើដើម្បីកាត់ទសភាគចេញ ប៉ុន្តែ Math.trunc(x) និយាយអ្វីដែលអ្នកមានន័យ ហើយមិនខូចសម្រាប់លេខលើសពី 32 bit ទេ។
9. រូបមន្ត៖ bits.js
បង្កើត src/bits.js ដែលមាន permission flag និងប្រតិបត្តិការ flag ទាំងបួន៖
export const READ = 0b100; // 4
export const WRITE = 0b010; // 2
export const EXEC = 0b001; // 1
export function hasFlag(value, flag) {
return (value & flag) === flag;
}
export function setFlag(value, flag) {
return value | flag;
}
export function clearFlag(value, flag) {
return value & ~flag;
}
export function toggleFlag(value, flag) {
return value ^ flag;
}
function triple(bits) {
return (
(hasFlag(bits, READ) ? "r" : "-") +
(hasFlag(bits, WRITE) ? "w" : "-") +
(hasFlag(bits, EXEC) ? "x" : "-")
);
}
export function toUnixMode(mode) {
const owner = (mode >> 6) & 0b111;
const group = (mode >> 3) & 0b111;
const other = mode & 0b111;
return triple(owner) + triple(group) + triple(other);
}
triple គឺជា helper តូចមួយដែលមិនត្រូវបាន export៖ វាបំប្លែងបី bit ទៅជាអត្ថបទដូចជា r-x។ toUnixMode បំបែក mode ទៅជាបីក្រុមរបស់វា ដូចក្នុងផ្នែកទី 5 ហើយភ្ជាប់បីបំណែកចូលគ្នា។
បន្ថែមវាទៅ src/index.js៖
export * from "./bits.js";
(រក្សាបន្ទាត់ពីជំពូកមុនៗ រួមទាំង export * from "./numbers.js";។)
បន្ទាប់មកបន្ថែមទៅ demo.js៖
import {
READ, WRITE, EXEC,
hasFlag, setFlag, clearFlag, toggleFlag, toUnixMode,
} from "./src/index.js";
let perms = READ | WRITE;
console.log(perms); // 6
console.log(hasFlag(perms, WRITE)); // true
console.log(hasFlag(perms, EXEC)); // false
perms = setFlag(perms, EXEC);
console.log(perms); // 7
perms = clearFlag(perms, WRITE);
console.log(perms); // 5
perms = toggleFlag(perms, WRITE);
console.log(perms); // 7
console.log(toUnixMode(0o755)); // rwxr-xr-x
console.log(toUnixMode(0o644)); // rw-r--r--
console.log(toUnixMode(0o754)); // rwxr-xr--
console.log(toUnixMode(0o600)); // rw-------
ប្រសិនបើ demo.js របស់អ្នកមានបន្ទាត់ import ពី ./src/index.js រួចហើយ សូមបញ្ចូលឈ្មោះទៅក្នុង import តែមួយ ជំនួសឲ្យការបន្ថែមទីពីរ។ រត់៖
node demo.js
បន្ទាត់ថ្មីបោះពុម្ព 6, true, false, 7, 5, 7 ហើយបន្ទាប់មកជាខ្សែអក្សរ rwx ទាំងបួនដែលបង្ហាញក្នុង comment។
10. សាកល្បងដោយខ្លួនឯង
- ដោយក្រដាសជាមុន។ គណនា
0b1111 & 0b0101,0b1010 | 0b0101និង0b1110 ^ 0b0111ដោយតម្រឹម bit។ ពិនិត្យមួយៗក្នុង Node ដោយ.toString(2)។ - បន្ថែម flag ទីបួន។ បន្ថែម flag
DELETEទៅសំណុំសិទ្ធិរបស់អ្នក ដែលមិនបុកនឹងREAD,WRITEឬEXEC។ តើវាគួរមានតម្លៃអ្វី? តើមានអ្វីកើតឡើងចំពោះtoUnixModeប្រសិនបើអ្នកបញ្ជូនលេខដែលមាន flag នោះ? - អាន mode។ តើ
chmod 640និងchmod 700ជាទម្រង់rwxយ៉ាងដូចម្តេច? ពិនិត្យចម្លើយរបស់អ្នកដោយtoUnixMode(0o640)និងtoUnixMode(0o700)។ - សាងសង់ផ្ទុយវិញ។ សរសេរ
fromUnixMode("rwxr-xr--")ដែលត្រឡប់លេខ0o754។ (គន្លឹះ៖r,w,xនីមួយៗជា flag; បូកREAD,WRITEឬEXECហើយ shift ក្រុមនីមួយៗទៅកន្លែងដោយ<<។) - ជំនួយការ feature flag។ ដោយប្រើ object
Featureពីផ្នែកទី 6 សរសេរlistFlags(value)ដែលត្រឡប់ឈ្មោះនៃ flag ទាំងអស់ដែលបើក ឧទាហរណ៍["DARK_MODE", "ADMIN"]សម្រាប់9។ (គន្លឹះ៖Object.entriesនិងhasFlag។) - ទម្លុះដែនកំណត់ 32-bit។ រត់
1 << 31,1 << 32និង(1 << 31) >>> 0។ បន្ទាប់មកសរសេរ1 << 40ឡើងវិញដោយប្រើBigInt។ ពន្យល់ដោយពាក្យរបស់អ្នកថា ហេតុអ្វីកំណែធម្មតាផ្តល់ចម្លើយខុស។
ឥឡូវនេះអ្នកអាចរក្សាទុក និងសាកល្បងតម្លៃបាទ/ចាសជាច្រើនក្នុងលេខតែមួយ។ ក្នុង Boolean Logic យើងថយក្រោយពី bit មកកាន់ច្បាប់ true/false ដែលនៅពីក្រោយរាល់ប្រយោគ if ហើយរៀនរបៀបសម្រួលលក្ខខណ្ឌដែលស្មុគស្មាញ។
ទិញកាហ្វេជូនខ្ញុំ
ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!