JavaScript کا Math object اس زبان کا ایک خاموش یوٹیلیٹی بیلٹ (utility belt) ہے۔ آپ اسے کبھی انسٹینشی ایٹ (instantiate) نہیں کرتے۔ آپ اسے کبھی امپورٹ (import) نہیں کرتے۔ یہ ہر رن ٹائم (runtime) میں موجود ہوتا ہے، جو پکسل ویلیو کو راؤنڈ کرنے سے لے کر ڈائس (dice) کا رینڈم رول جنریٹ کرنے تک ہر چیز کو سنبھالنے کے لیے تیار رہتا ہے۔ چونکہ Math ایک اسٹیٹک (static) آبجیکٹ ہے، اس لیے اس کا ہر میتھڈ (method) اور پراپرٹی (property) براہ راست نیم اسپیس (namespace) سے جڑا ہوتا ہے۔ آپ Math.PI لکھتے ہیں، نہ کہ new Math().PI۔ یہ ڈیزائن کا انتخاب چیزوں کو سادہ رکھتا ہے، لیکن اس کا مطلب یہ بھی ہے کہ اس آبجیکٹ میں کچھ ایسی پیچیدگیاں (sharp edges) ہیں جنہیں پروڈکشن لاجک (production logic) کے لیے استعمال کرنے سے پہلے سمجھنا ضروری ہے۔
بغیر کنسٹرکٹر کے ایک اسٹیٹک آبجیکٹ
زیادہ تر بلٹ ان (built-in) JavaScript آبجیکٹس چاہتے ہیں کہ آپ ایک انسٹنس (instance) بنائیں۔ آپ new Date() یا new Array() کال کرتے ہیں۔ Math اس سے انکار کرتا ہے۔ اسے متعلقہ فنکشنز اور کانسٹنٹ (constants) کے ایک نیم اسپیس کے طور پر ڈیزائن کیا گیا ہے جو پرائمٹیو (primitive) Number ٹائپ پر کام کرتے ہیں۔ Math.sqrt(16) کال کریں اور آپ کو 4 ملے گا۔ اگر آپ new کی ورڈ استعمال کرنے کی کوشش کریں گے تو انجن TypeError دے گا۔ یہ پیٹرن میموری کو صاف رکھتا ہے اور یہ اشارہ دیتا ہے کہ Math خالصتاً فنکشنل (functional) ہے۔ یہ ان پٹ لیتا ہے، آؤٹ پٹ دیتا ہے، اور کسی چیز کو تبدیل (mutate) نہیں کرتا۔
ایک سخت حد ہے جسے یاد رکھنا ضروری ہے: Math معیاری IEEE 754 نمبروں کے ساتھ کام کرتا ہے۔ یہ BigInt کے ساتھ کام نہیں کرتا۔ اگر آپ Math.round() یا Math.abs() کو BigInt پاس کریں گے تو آپ کو TypeError ملے گا۔ اگر آپ کی ایپلی کیشن 64-bit انٹیجرز یا اس سے بڑے نمبروں کے ساتھ کام کرتی ہے، تو آپ کو انہیں تبدیل کرنا ہوگا یا اس کے بجائے نیٹیو (native) BigInt آپریٹرز کے ساتھ حساب کتاب کرنا ہوگا۔
وہ کانسٹنٹ جنہیں آپ حقیقت میں استعمال کرتے ہیں
Math آبجیکٹ کئی نیومیرک کانسٹنٹ (numeric constants) فراہم کرتا ہے جو آپ کو میجک نمبرز (magic numbers) کو ہارڈ کوڈ (hard-code) کرنے سے بچاتے ہیں۔
Math.PIوہ جانا پہچانا 3.14159... ہے، جو دائروں، ٹرگنومیٹری (trigonometry)، یا ڈگریوں کو ریڈینز (radians) میں تبدیل کرنے کے لیے ضروری ہے۔Math.Eآئلر کا نمبر (Euler's number) ہے، جو تقریباً 2.718 ہے۔ یہ ایکسپونینشل گروتھ کرو (exponential growth curves)، کمپاؤنڈ انٹرسٹ (compound interest) کے حساب کتاب، اور لاگتھمک اسکیلز (logarithmic scales) میں نظر آتا ہے۔Math.SQRT2دو کا مربع جزر (square root) ہے، جو تقریباً 1.414 ہے۔ یہ اس وقت کارآمد ہوتا ہے جب آپ کو مربع کا وتر (diagonal) چاہیے ہو یا سادہ جیومیٹری میں ویکٹرز (vectors) کو نارملائز کرنا ہو۔Math.LN22 کا نیچرل لاگتھم (natural logarithm) ہے، جو تقریباً 0.693 ہے۔ آپ اسے ان الگورتھمز میں دیکھیں گے جو بائنری ٹریز (binary trees)، انفارمیشن انٹروپی (information entropy)، یا log-base-2 میتھ پر مبنی ٹائم کمپلیکسٹی (time complexity) کے تجزیے سے متعلق ہوں۔
یہ ویلیوز مکمل طور پر ڈبل پریسیژن فلوٹس (double-precision floats) ہیں۔ چونکہ یہ پراپرٹیز ہیں نہ کہ میتھڈز، اس لیے آپ انہیں بغیر بریکٹ کے استعمال کرتے ہیں۔
راؤنڈنگ، سائنز، اور ایبسولیوٹ ویلیوز
Math کے سب سے عام کاموں میں نمبروں کو درست (clean up) کرنا شامل ہے۔ JavaScript آپ کو راؤنڈنگ کے چار میتھڈز دیتا ہے، اور وہ ایک جیسے کام نہیں کرتے، خاص طور پر جب آپ مثبت نمبروں سے باہر نکلتے ہیں۔
Math.abs(x) کسی نمبر کی مقدار (magnitude) واپس کرتا ہے۔ اسے -42 دیں اور آپ کو 42 ملے گا۔ یہ اس وقت مفید ہے جب آپ سمت کے بجائے فاصلے کی پرواہ کرتے ہوں۔ ٹائم اسٹیمپ (timestamps) کا موازنہ کرنا، UI میں ڈریگ ڈیلٹا (drag deltas) کا حساب لگانا، یا یہ چیک کرنا کہ آیا کوئی اندازہ غلطی کے مارجن (error margin) کے اندر ہے، اس کی مثالیں ہیں۔
Math.round(x) اسکول لیول کا راؤنڈر ہے۔ یہ قریب ترین انٹیجر (integer) لیتا ہے، اور آدھے (halves) کو اگلے مثبت انٹیجر تک راؤنڈ کرتا ہے۔ چنانچہ 4.4 بن جاتا ہے 4، اور 4.5 بن جاتا ہے 5۔
Math.ceil(x) ہمیشہ اگلے انٹیجر تک اوپر کی طرف راؤنڈ کرتا ہے۔ 4.1 بن جاتا ہے 5، اور -4.9 بن جاتا ہے -4۔ یہ آخری بات لوگوں کو حیران کرتی ہے۔ کیونکہ نمبر لائن پر -4، -4.9 سے بڑا ہے، اس لیے سیلنگ (ceiling) منفی نمبروں کے لیے صفر کی طرف بڑھتی ہے۔
Math.floor(x) اس کے برعکس ہے۔ یہ ہمیشہ نیچے کی طرف راؤنڈ کرتا ہے۔ 4.9 بن جاتا ہے 4، اور -4.1 بن جاتا ہے -5۔ اگر آپ سرچ رزلٹس کی پیجینیشن (pagination) کر رہے ہیں یا فکسڈ سائز کے میموری بلاکس مختص کر رہے ہیں، تو عام طور پر floor ہی آپ کی ضرورت ہوتی ہے۔
Math.trunc(x) ڈیسیمل (decimal) کو مکمل طور پر ختم کر دیتا ہے، صرف انٹیجر حصہ چھوڑ دیتا ہے۔ درحقیقت، یہ سائن (sign) کی پرواہ کیے بغیر صفر کی طرف بڑھتا ہے۔ 4.9 بن جاتا ہے 4، اور -4.9 بن جاتا ہے -4۔ اگر آپ ایسی زبانوں سے لاجک پورٹ کر رہے ہیں جو فلوٹس کو انٹیجرز میں تبدیل کرنے کے لیے ٹرنکیٹنگ (truncating) کا استعمال کرتی ہیں، تو یہ آپ کا بہترین دوست ہے۔
آخر میں، Math.sign(x) آپ کو بتاتا ہے کہ کوئی ویلیو صفر کے کس طرف ہے۔ یہ مثبت کے لیے 1، منفی کے لیے -1، مثبت صفر کے لیے 0، منفی صفر کے لیے -0، اور کسی بھی ایسی چیز کے لیے جو نمبر نہ ہو NaN واپس کرتا ہے۔ یہ if-else چین لکھے بغیر سمت کے بنیاد پر فیصلہ کرنے کا ایک مختصر طریقہ ہے۔
رینڈم نمبرز جنریٹ کرنا
Math.random() 0 (بشمول) سے 1 (مستثنیٰ) تک ایک سوڈو رینڈم (pseudo-random) فلوٹ پیدا کرتا ہے۔ یہ کرپٹوگرافک طور پر محفوظ (cryptographically secure) نہیں ہے، اس لیے اسے پاس ورڈ جنریشن، ٹوکن تخلیق، یا حقیقی رقم سے متعلق کسی بھی کام کے لیے استعمال نہ کریں۔
