Function, ការលូតលាស់ និង Logarithm
មាតិកា
- Function គឺជាម៉ាស៊ីនពី Input ទៅ Output
- រូបរាងបីនៃការលូតលាស់
- ស្វ័យគុណ និង Exponent
- ហេតុអ្វីការលូតលាស់ Exponential គ្រោះថ្នាក់
- Logarithm៖ តើខ្ញុំអាចកាត់ពាក់កណ្តាលបានប៉ុន្មានដង?
- Binary Search៖ មួយក្នុងមួយលានក្នុង 20 ជំហាន
- Logarithm ក្នុង JavaScript
- ការលូតលាស់ផ្សំ និងពេលវេលាកើនទ្វេដង
- រូបមន្ត៖ Module growth
- សាកល្បងដោយខ្លួនឯង
1. Function គឺជាម៉ាស៊ីនពី Input ទៅ Output
អ្នកសរសេរ function រួចហើយ។ ក្នុងគណិតវិទ្យា function គឺជាគំនិតដូចគ្នា៖ ម៉ាស៊ីនដែលទទួល input ហើយតែងតែផ្តល់ output ដូចគ្នាសម្រាប់ input នោះ។ ដាក់ 5 ចូល ទទួលបាន 10 ចេញ។ ថ្ងៃស្អែកដាក់ 5 ចូលម្តងទៀត ក៏ទទួលបាន 10 ចេញដដែល។
function double(x) {
return x * 2;
}
console.log(double(5)); // 10
console.log(double(0)); // 0
គណិតវិទូសរសេរវាថា f(x) = 2x អានថា "f នៃ x ស្មើ 2 គុណ x"។ x គឺ input ហើយ f(x) គឺ output។ គ្មានអ្វីលើសពីនេះទេ។
តារាង input-to-output គឺជាវិធីលឿនបំផុតដើម្បីយល់ពី function ណាមួយ។ នេះគឺ f(x) = 3x + 2៖
function f(x) {
return 3 * x + 2;
}
console.log(f(0), f(1), f(2)); // 2 5 8
រាល់ពេល x កើនឡើង 1 output កើនឡើង 3។ ចងចាំលំនាំស្ថិរភាពបែបនោះ វាគឺជារូបរាងទីមួយក្នុងបីដែលអ្នកត្រូវស្គាល់។
ហេតុអ្វីរឿងនេះសំខាន់សម្រាប់អ្នកសរសេរកម្មវិធី? ព្រោះសំណួរ "តើការងារលូតលាស់យ៉ាងណាពេលទិន្នន័យលូតលាស់?" គឺជាសំណួរអំពី function។ Input គឺទំហំនៃទិន្នន័យរបស់អ្នក (ឧទាហរណ៍ ចំនួនអ្នកប្រើ) ហើយ output គឺបរិមាណការងារ (ពេលវេលា, ជំហាន, អង្គចងចាំ) ដែលកូដរបស់អ្នកត្រូវការ។ ជំពូកបន្ទាប់បំលែងរឿងនេះទៅជាសញ្ញា Big-O។
2. រូបរាងបីនៃការលូតលាស់
ឱ្យ n ជាទំហំនៃ input របស់អ្នក។ ប្រៀបធៀប function ងាយៗបី៖
n | Linear: n | Quadratic: n * n | Exponential: 2^n |
|---|---|---|---|
| 1 | 1 | 1 | 2 |
| 2 | 2 | 4 | 4 |
| 3 | 3 | 9 | 8 |
| 4 | 4 | 16 | 16 |
| 5 | 5 | 25 | 32 |
| 10 | 10 | 100 | 1,024 |
| 100 | 100 | 10,000 | ប្រហែល 1.27 x 10^30 |
| 1000 | 1000 | 1,000,000 | ប្រហែល 1.07 x 10^301 |
អ្នកអាចបោះពុម្ពតារាងនេះដោយខ្លួនឯង៖
for (const n of [1, 2, 3, 4, 5, 10, 100, 1000]) {
console.log(n, n, n * n, 2 ** n);
}
// 10 10 100 1024
// 100 100 10000 1.2676506002282294e+30
// 1000 1000 1000000 1.0715086071862673e+301
(2 ** n គឺជា power operator របស់ JavaScript ដែលនឹងពន្យល់បន្ទាប់ ហើយ e+30 មានន័យថា "គុណ 10 ស្វ័យគុណ 30"។)
ទាំងបីចាប់ផ្តើមពីតម្លៃស្រដៀងគ្នា រួចដាច់ចេញពីគ្នា៖
- ការលូតលាស់ Linear៖ input កើនទ្វេដង ការងារកើនទ្វេដង។ ការអានគ្រប់ជួរនៃឯកសារគឺ linear។
- ការលូតលាស់ Quadratic៖ input កើនទ្វេដង ការងារកើន បួនដង។ ការប្រៀបធៀបអ្នកប្រើម្នាក់ៗជាមួយអ្នកប្រើផ្សេងទៀតគ្រប់គ្នាគឺ quadratic។
- ការលូតលាស់ Exponential៖ បន្ថែម មួយ ទៅ input ហើយការងារកើនទ្វេដង។ ការសាកល្បងគ្រប់បន្សំបើក/បិទដែលអាចមានរបស់កុងតាក់
nគឺ exponential។
នៅ n = 100 ជួរ exponential មាន 31 ខ្ទង់។ គ្មានកុំព្យូទ័រណាអាចបញ្ចប់ជំហានច្រើនយ៉ាងនេះទេ។ នេះគឺជារូបភាពសំខាន់បំផុតតែមួយគត់នៃជំពូក។
3. ស្វ័យគុណ និង Exponent
ស្វ័យគុណ (power) មានន័យថាការគុណម្តងហើយម្តងទៀត។ ក្នុង 2^5 លេខ 2 គឺជា base ហើយ 5 គឺជា exponent ហើយវាមានន័យថា 2 ប្រាំដងគុណគ្នា៖
2^5 = 2 * 2 * 2 * 2 * 2 = 32
JavaScript សរសេរវាជា 2 ** 5 ឬ Math.pow(2, 5)។
console.log(2 ** 10); // 1024
console.log(2 ** 20); // 1048576
console.log(2 ** 30); // 1073741824
console.log(10 ** 3); // 1000
console.log(10 ** 6); // 1000000
ករណីពិសេសបីដែលគួរទន្ទេញ៖
| Expression | តម្លៃ | ហេតុអ្វី |
|---|---|---|
x ** 1 | x | ច្បាប់ចម្លងមួយនៃ x |
x ** 0 | 1 | ផលគុណទទេ ដូច្នេះ 5 ** 0 គឺ 1 |
2 ** -1 | 0.5 | exponent អវិជ្ជមានមានន័យថា "មួយចែកនឹង" |
អ្នកធ្លាប់ឃើញ 2^10 = 1024 ពីមុន៖ នោះគឺជា "kilo" នៃកុំព្យូទ័រ ហើយជាមូលហេតុដែល 1 KiB ស្មើ 1,024 byte។ ក៏សូមកត់សម្គាល់ 2 ** 32 = 4294967296 និង 2 ** 31 - 1 = 2147483647៖ ទាំងនេះគឺជាដែនកំណត់ integer ពី Integer, Overflow និងភាពជាក់លាក់។ រាល់ bit បន្ថែមធ្វើឱ្យចំនួនតម្លៃដែលអ្នករក្សាទុកបានកើនទ្វេដង។
ច្បាប់ងាយស្រួលមួយ៖ 2^a * 2^b = 2^(a + b)។ ឧទាហរណ៍ 2^3 * 2^4 = 8 * 16 = 128 = 2^7។ ការគុណស្វ័យគុណដែលមាន base ដូចគ្នាគឺបូក exponent។ ច្បាប់នោះគឺជាអាថ៌កំបាំងដែលធ្វើឱ្យ logarithm ដំណើរការ។
4. ហេតុអ្វីការលូតលាស់ Exponential គ្រោះថ្នាក់
ការលូតលាស់ exponential ចាប់ផ្តើមយឺតៗ ដែលជាអ្វីដែលបោកបញ្ឆោតមនុស្ស។ រូបភាពបីពីពិភពពិត៖
ក្តារអុក។ ដាក់គ្រាប់អង្ករ 1 លើប្រអប់ទីមួយ, 2 លើទីពីរ, 4 លើទីបី ទ្វេដងគ្រប់ប្រអប់។ នៅប្រអប់ទី 64 ចំនួនគឺ 2^63 ប្រហែល 9.2 x 10^18 គ្រាប់ ច្រើនជាងអង្ករដែលធ្លាប់ដាំមក។
បត់ក្រដាស។ សន្លឹកក្រដាសមួយក្រាស់ប្រហែល 0.1 មីលីម៉ែត្រ។ រាល់ការបត់ធ្វើឱ្យកម្រាស់ទ្វេដង។ បន្ទាប់ពីបត់ 42 ដង ជង់មានកម្ពស់ 0.1 * 2^42 mm ដែលប្រហែល 440,000 គីឡូម៉ែត្រ ឆ្ងាយជាងព្រះច័ន្ទ (ប្រហែល 384,000 km)៖
console.log((0.1 * 2 ** 42) / 1e6); // 439804.65111040004 (គីឡូម៉ែត្រ)
លេខសម្ងាត់។ លេខសម្ងាត់ 8 តួអក្សរដែលប្រើតែអក្សរតូចមាន 26^8 លទ្ធភាព។ ការបន្ថែមប្រវែងគឺគុណ ដូច្នេះរាល់តួអក្សរបន្ថែមធ្វើឱ្យការទាយពិបាកជាង 26 ដង៖
console.log(26 ** 8); // 208827064576 (ប្រហែល 208 ពាន់លាន)
console.log(62 ** 8); // 218340105584896 (អក្សរ + ខ្ទង់, ប្រហែល 218 ទ្រីលាន)
នោះជាមូលហេតុដែលលេខសម្ងាត់វែងឈ្នះលេខសម្ងាត់ខ្លី "ឆ្លាត" ហើយជាមូលហេតុដែលសំណួរសុវត្ថិភាពដែលមានចម្លើយអាចមានតែ 1,000 គឺគ្មានប្រយោជន៍។
ក្នុងកូដ ការលូតលាស់ exponential លេចឡើងក្នុង recursion ដែលហៅខ្លួនឯងពីរដង។ ឧទាហរណ៍ដ៏ល្បីគឺ Fibonacci៖
function fib(n) {
return n < 2 ? n : fib(n - 1) + fib(n - 2);
}
console.log(fib(10)); // 55
console.log(fib(20)); // 6765
console.log(fib(30)); // 832040
វាដំណើរការ ប៉ុន្តែរាល់ការហៅបង្កើតការហៅពីរទៀត។ fib(20) ធ្វើការហៅ 21,891 ដង, fib(25) ធ្វើ 242,785 ហើយ fib(30) ធ្វើ 2,692,537។ រាល់ +5 ក្នុង input គុណការងារប្រហែល 11។ សាកល្បង fib(45) ហើយ terminal របស់អ្នកនឹងគាំងយូរ។
ច្បាប់ជាក់ស្តែង៖ កូដ linear និង quadratic អាចសង្គ្រោះបានដោយផ្នែករឹងប្រសើរជាង។ កូដ exponential មិនអាចទេ។ អ្នកត្រូវផ្លាស់ប្តូរ algorithm។
5. Logarithm៖ តើខ្ញុំអាចកាត់ពាក់កណ្តាលបានប៉ុន្មានដង?
Logarithm គឺជាផ្ទុយនៃស្វ័យគុណ។ ស្វ័យគុណសួរថា "តើខ្ញុំទទួលបានអ្វីបើគុណ 2 នឹងខ្លួនឯង 10 ដង?" ហើយចម្លើយគឺ 1024។ Logarithm សួរបញ្ច្រាស់៖ "តើខ្ញុំត្រូវគុណ 2 ប៉ុន្មានដងដើម្បីទៅដល់ 1024?" ហើយចម្លើយគឺ 10។
2^10 = 1024 <=> log2(1024) = 10
អាន log2(1024) ថា "log base 2 នៃ 1024"។ លេខ 2 តូចគឺជា base ហើយចម្លើយគឺជា exponent។
នេះគឺជាវិធីគិតដែលងាយបំផុត៖ log2(n) គឺប្រហែលជាចំនួនដងដែលអ្នកអាចកាត់ n ជាពាក់កណ្តាលមុននឹងទៅដល់ 1។ ចាប់ផ្តើមពី 1,000 ធាតុ ហើយបន្តកាត់ពាក់កណ្តាល៖
1000 -> 500 -> 250 -> 125 -> 62 -> 31 -> 15 -> 7 -> 3 -> 1
នោះគឺ 9 ដងនៃការកាត់ពាក់កណ្តាល ហើយ log2(1000) គឺប្រហែល 9.97។ ជិតគ្នា ហើយភាពខុសគ្នាគ្រាន់តែជាការបង្គត់ប្រភាគ។
Base ផ្សេងៗដំណើរការដូចគ្នា៖
| Expression | អត្ថន័យ | តម្លៃ |
|---|---|---|
log2(8) | 2 គុណអ្វីបាន 8? 2^3 | 3 |
log10(1000) | 10^3 = 1000 | 3 |
log3(81) | 3^4 = 81 | 4 |
log5(125) | 5^3 = 125 | 3 |
ព្រោះ log10(n) រាប់ប្រហែល ខ្ទង់ របស់ n ហើយ log2(n) រាប់ប្រហែល bit របស់ n logarithm លូតលាស់យឺតគួរឱ្យភ្ញាក់ផ្អើល៖
n | log2(n) |
|---|---|
| 1,000 | ប្រហែល 10 |
| 1,000,000 | ប្រហែល 20 |
| 1,000,000,000 | ប្រហែល 30 |
| 1,000,000,000,000 | ប្រហែល 40 |
ការគុណ input នឹង 1,000 បន្ថែមតែ 10 ទៅចម្លើយ។ algorithm logarithmic ស្ទើរតែមិនកត់សម្គាល់ថា input របស់វាធំប៉ុនណាទេ ហើយនោះជាអ្វីដែលធ្វើឱ្យ logarithm មានតម្លៃខ្លាំងសម្រាប់អ្នកសរសេរកម្មវិធី។
6. Binary Search៖ មួយក្នុងមួយលានក្នុង 20 ជំហាន
នេះគឺជាកន្លែងដែល logarithm រកស៊ីចិញ្ចឹមជីវិត។ ឧបមាថាខ្ញុំជ្រើសលេខសម្ងាត់ពី 1 ដល់ 1,000,000 ហើយអ្នកត្រូវទាយវា។ បន្ទាប់ពីការទាយនីមួយៗ ខ្ញុំប្រាប់ថា "ខ្ពស់ជាង" ឬ "ទាបជាង"។
យុទ្ធសាស្ត្រ linear (ទាយ 1 បន្ទាប់មក 2 បន្ទាប់មក 3...) អាចត្រូវទាយមួយលានដង។ យុទ្ធសាស្ត្រឆ្លាតគឺ ទាយចំកណ្តាល រាល់ពេល៖
- ទាយ 500,000។ ប្រសិនបើ "ទាបជាង" អ្នកទើបតែលុបបំបាត់ពាក់កណ្តាលនៃលទ្ធភាពទាំងអស់។
- ទាយ 250,000 ហើយម្តងទៀតពាក់កណ្តាលនៃអ្វីដែលនៅសល់បាត់ទៅ។
- បន្តទៅមុខ។ រាល់ការទាយធ្វើឱ្យ pool ថយពាក់កណ្តាល។
Pool រួមតូចដូច 1,000,000 -> 500,000 -> 250,000 -> ... -> 1។ តើនោះជាការកាត់ពាក់កណ្តាលប៉ុន្មានដង? 2^20 = 1,048,576 ដែលនៅលើមួយលានបន្តិច ដូច្នេះ ទាយ 20 ដងគឺគ្រប់គ្រាន់ជានិច្ច។ សម្រាប់ធាតុមួយ ពាន់លាន គឺមានតែ 30។
យុទ្ធសាស្ត្រនេះហៅថា binary search។ វាតម្រូវឱ្យទិន្នន័យ តម្រៀបរួច (sorted) (ដើម្បីឱ្យ "ខ្ពស់ជាង" និង "ទាបជាង" មានន័យ) ដូចជាសៀវភៅទូរស័ព្ទ, វចនានុក្រម ឬ array នៃ ID ដែលតម្រៀបរួច។ នេះជាកំណែដែលដំណើរការ៖
function binarySearch(sorted, target) {
let low = 0;
let high = sorted.length - 1;
while (low <= high) {
const mid = Math.floor((low + high) / 2);
if (sorted[mid] === target) return mid;
if (sorted[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1;
}
const ids = Array.from({ length: 1_000_000 }, (_, i) => i * 2);
console.log(binarySearch(ids, 1999998)); // 999999
console.log(binarySearch(ids, 7)); // -1
low និង high សម្គាល់ផ្នែកនៃ array ដែលនៅក្នុងល្បែង។ រាល់ loop មើលកណ្តាល (mid) បន្ទាប់មកបោះចោលពាក់កណ្តាលដែលមិនអាចមាន target។ Math.floor បង្គត់ចុះ ដូច្នេះ mid ជា index ទាំងមូល ហើយ function ត្រឡប់ -1 ពេលរកមិនឃើញធាតុ។ សញ្ញា underscore ក្នុង 1_000_000 គ្រាន់តែជាជំនួយឱ្យងាយអានលេខធំៗ។
Loop ធម្មតាអាចពិនិត្យធាតុរហូតដល់មួយលាន ចំណែកនេះពិនិត្យប្រហែល 20។ អ្នកនឹងប្រណាំងទាំងពីរឱ្យបានត្រឹមត្រូវនៅក្នុង សញ្ញា Big-O។
7. Logarithm ក្នុង JavaScript
JavaScript ផ្តល់ function logarithm បីដល់អ្នក៖
console.log(Math.log2(1024)); // 10
console.log(Math.log10(1000)); // 3
console.log(Math.log(Math.E)); // 1 (natural log, base e = 2.718...)
Math.log គឺជា natural logarithm ដែលមាន base e (ថេរពិសេសមួយ ប្រហែល 2.71828 ដែលលេចឡើងក្នុងការលូតលាស់ និងការរលាយ)។ អ្នកកម្រត្រូវការវាដោយផ្ទាល់ ប៉ុន្តែវាផ្តល់ជាមធ្យោបាយគណនា log ក្នុង base ណាមួយ។ ច្បាប់ change of base ថា៖
log_b(x) = ln(x) / ln(b)
function logBase(base, x) {
return Math.log(x) / Math.log(base);
}
console.log(logBase(2, 1024)); // 10
console.log(logBase(5, 125)); // 3.0000000000000004
console.log(logBase(3, 81)); // 4.000000000000001
console.log(logBase(10, 1000)); // 2.9999999999999996
មើលឱ្យជិត៖ ចម្លើយគឺ ស្ទើរតែ ជាចំនួនគត់ មិនជាក់លាក់ទេ។ នេះគឺជាបញ្ហា floating-point ពីជំពូកមុនដែលលេចឡើងម្តងទៀត។ ពេលណាចម្លើយពិតគួរជា integer ត្រូវបង្គត់វា ឬប្រៀបធៀបដោយ tolerance (nearlyEqual)។ ពេលអាចធ្វើបាន សូមប្រើ Math.log2 និង Math.log10 ដែលមានសម្រាប់ជាក់លាក់។
ការពិតពីរទៀតដែលត្រូវចងចាំ៖
console.log(Math.log(0)); // -Infinity
console.log(Math.log(-1)); // NaN
អ្នកអាចយក log បានតែនៃលេខវិជ្ជមានប៉ុណ្ណោះ។ ហើយចំនួនទាយអតិបរមាដែល binary search ត្រូវការសម្រាប់ n ធាតុគឺ Math.ceil(Math.log2(n + 1))៖
console.log(Math.ceil(Math.log2(1_000_000 + 1))); // 20
console.log(Math.ceil(Math.log2(1000 + 1))); // 10
Math.ceil បង្គត់ ឡើង ព្រោះប្រភាគនៃការទាយមួយនៅតែត្រូវចំណាយការទាយទាំងមូលមួយ។
8. ការលូតលាស់ផ្សំ និងពេលវេលាកើនទ្វេដង
ការលូតលាស់ exponential មិនមែនគ្រាន់តែជាគ្រោះថ្នាក់ទេ វាក៏ជារបៀបដែលលុយលូតលាស់ដែរ។ ឧបមាថាអ្នកដាក់ $1,000 ក្នុងគណនីសន្សំដែលបង់ 7% ក្នុងមួយឆ្នាំ។ រាល់ឆ្នាំសមតុល្យត្រូវគុណនឹង 1.07 (ដើមបូក 7%)។ បន្ទាប់ពី y ឆ្នាំ៖
balance = principal * (1 + rate) ^ years
នេះគឺជា ការលូតលាស់ផ្សំ (compound growth) ព្រោះការប្រាក់នៃឆ្នាំនីមួយៗក៏រកការប្រាក់ដែរ។ ក្នុង JavaScript៖
function compound(principal, ratePercent, years) {
return principal * (1 + ratePercent / 100) ** years;
}
for (const y of [0, 5, 10, 20, 30]) {
console.log(y, compound(1000, 7, y).toFixed(2));
}
// 0 1000.00
// 5 1402.55
// 10 1967.15
// 20 3869.68
// 30 7612.26
10 ឆ្នាំដំបូងបន្ថែមប្រហែល $967 ហើយ 10 ឆ្នាំចុងក្រោយបន្ថែមប្រហែល $3,743។ អត្រាដូចគ្នា ប៉ុន្តែ base ធំជាង៖ ខ្សែកោងកោងឡើងលើ។ វាគឺជារូបភាពដូចជួរ 2^n ដែរ គ្រាន់តែមាន base ទន់ភ្លន់ជាង 1.07។
ឥឡូវសំណួរ "តើត្រូវប្រើពេលប៉ុន្មានទើបលុយរបស់ខ្ញុំកើនទ្វេដង?" គឺជា logarithm៖ តើត្រូវគុណនឹង 1.07 ប៉ុន្មានដងដើម្បីទៅដល់ 2? ចម្លើយគឺ log(2) / log(1.07)៖
function doublingTime(ratePercent) {
return Math.log(2) / Math.log(1 + ratePercent / 100);
}
console.log(doublingTime(7).toFixed(2)); // 10.24
console.log(doublingTime(1).toFixed(2)); // 69.66
console.log(doublingTime(10).toFixed(2)); // 7.27
ត្រង់ 7% លុយរបស់អ្នកកើនទ្វេដងក្នុងរយៈពេលប្រហែល 10.2 ឆ្នាំ។ មនុស្សប្រើ ច្បាប់ 72 (rule of 72) ជាផ្លូវកាត់ក្នុងចិត្ត៖ យក 72 ចែកនឹងអត្រា។ 72 / 7 គឺប្រហែល 10.3 ជិតនឹងចម្លើយពិតណាស់។
គណិតវិទ្យាដូចគ្នាពិពណ៌នាអ្វីដែលលូតលាស់ក្នុងប្រព័ន្ធ របស់អ្នក៖ សេវាកម្មដែលចរាចរណ៍កើន 5% រៀងរាល់សប្តាហ៍នឹងកើនទ្វេដងក្នុងរយៈពេលប្រហែល 14 សប្តាហ៍ មូលដ្ឋានទិន្នន័យដែលកើន 10% ក្នុងមួយខែនឹងកើនទ្វេដងក្នុងរយៈពេលប្រហែល 7 ខែ។ ការគិតតាមពេលវេលាកើនទ្វេដងជួយអ្នកឆ្លើយសំណួរ "តើយើងនឹងអស់ disk ឬ capacity ពេលណា?" មុននឹងវាក្លាយជាអាសន្ន។
ហើយវាក៏ដំណើរការបញ្ច្រាសដែរ។ បំណុលដែលមានអត្រាការប្រាក់ខ្ពស់ ឬ bug រីករាលដាលដែលធ្វើឱ្យរបាយការណ៍កំហុសកើនទ្វេដងរាល់ម៉ោង គឺជាការលូតលាស់ exponential ដែលអ្នកមិនចង់បាន។
9. រូបមន្ត៖ Module growth
បន្ថែមឧបករណ៍របស់ជំពូកនេះទៅ mathlab។ បង្កើត src/growth.js៖
// src/growth.js
// ចំនួនទាយអាក្រក់បំផុតដែល binary search ត្រូវការសម្រាប់ n ធាតុដែលតម្រៀបរួច។
export function stepsToBinarySearch(n) {
return Math.ceil(Math.log2(n + 1));
}
// Logarithm នៃ x ក្នុង base ណាមួយ (អាចខុសបន្តិចដោយសារកំហុស float)។
export function logBase(base, x) {
return Math.log(x) / Math.log(base);
}
// ឆ្នាំ (ឬរយៈពេល) ដើម្បីឱ្យអ្វីមួយដែលលូតលាស់ក្នុងអត្រា ratePercent កើនទ្វេដង។
export function doublingTime(ratePercent) {
return Math.log(2) / Math.log(1 + ratePercent / 100);
}
// តម្លៃបន្ទាប់ពីផ្សំ principal ក្នុងអត្រា ratePercent សម្រាប់ចំនួនឆ្នាំមួយ។
export function compound(principal, ratePercent, years) {
return principal * (1 + ratePercent / 100) ** years;
}
Re-export វាពី src/index.js៖
export * from "./growth.js";
បន្ថែមកូដនេះទៅ demo.js ហើយដំណើរការ node demo.js៖
import {
stepsToBinarySearch, logBase, doublingTime, compound,
} from "./src/growth.js";
console.log("--- growth ---");
console.log(stepsToBinarySearch(1000)); // 10
console.log(stepsToBinarySearch(1_000_000)); // 20
console.log(stepsToBinarySearch(1_000_000_000)); // 30
console.log(logBase(2, 1024)); // 10
console.log(logBase(3, 81)); // 4.000000000000001
console.log(doublingTime(7).toFixed(2)); // 10.24
console.log(compound(1000, 7, 10).toFixed(2)); // 1967.15
សូមកត់សម្គាល់ថា logBase(3, 81) មិនមែនជា 4 យ៉ាងជាក់លាក់ទេ។ នោះគឺជារឿងរំពឹងទុក ហើយជាការរំលឹកល្អឱ្យបង្គត់មុនបង្ហាញលទ្ធផលដល់អ្នកប្រើ។
10. សាកល្បងដោយខ្លួនឯង
- បង្កើតតារាងការលូតលាស់។ សរសេរ loop សម្រាប់
nពី 1 ដល់ 10 ដែលបោះពុម្ពn,n * n,n ** 3និង2 ** nលើបន្ទាត់មួយ។ តើនៅnប៉ុន្មានដែល2 ** nឈ្នះn ** 3ជាលើកដំបូង? (ពិនិត្យចម្លើយរបស់អ្នកជាមួយ output។) - រាប់ការកាត់ពាក់កណ្តាល។ សរសេរ
halvings(n)ដែលធ្វើn = Math.floor(n / 2)ម្តងហើយម្តងទៀតរហូតnជា 1 ដោយរាប់ជំហាន។ សាកល្បងជាមួយ1024និង1000000។ ប្រៀបធៀបជាមួយMath.log2(n)។ ហេតុអ្វី1000000ផ្តល់ 19 នៅទីនេះ ប៉ុន្តែ binary search ត្រូវការទាយ 20 ដង? - បញ្ហាបត់ក្រដាស។ តើត្រូវបត់សន្លឹកក្រដាស 0.1 mm ប៉ុន្មានដងដើម្បីលើសកម្ពស់ប្រាសាទអង្គរវត្ត (ប្រហែល 65 ម៉ែត្រ)? ប្រើ loop បន្ទាប់មកបញ្ជាក់ដោយ
Math.ceil(Math.log2(65 / 0.0001))។ - កម្លាំងលេខសម្ងាត់។ សរសេរ
passwordSpace(alphabetSize, length)ដោយប្រើ**។ ប្រៀបធៀបអក្សរតូច 8 តួ (26), អក្សរតូចធំលាយខ្ទង់ 8 តួ (62) និងអក្សរតូច 12 តួ។ មួយណាធំជាង? - តើយើងនឹងអស់ពេលណា? disk មួយមានទំហំទំនេរ 500 GB ហើយទិន្នន័យរបស់អ្នកកើន 8% ក្នុងមួយខែ និងប្រើ 100 GB ឥឡូវនេះ។ ដោយប្រើ
compoundរកខែដំបូងដែលទិន្នន័យលើស 500 GB។ (ជំនួយ៖ loop តាមខែ ឬគណនាMath.log(5) / Math.log(1.08)។) - ធ្វើឱ្យ
fibខូច។ វាស់ពេលfib(30)និងfib(35)ដោយconsole.time។ តើពេលវេលាកើនប្រហែលប៉ុន្មានដង? តើនោះបង្ហាញអ្វីអំពីfib(50)?
បន្ទាប់ យើងនឹងដាក់ឈ្មោះឱ្យវាក្យសព្ទការលូតលាស់នេះ ដែលអ្នកសរសេរកម្មវិធីគ្រប់គ្នាប្រើ ហើយរៀនអានរង្វិលជុំ (loop) ជ្រៅៗក្នុងមួយភ្លែតក្នុង សញ្ញា Big-O។
ទិញកាហ្វេជូនខ្ញុំ
ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!