Julia لغة متعددة الأغراض يمكن استخدامها في معظم مهام البرمجة. لكن في الواقع، يميل استخدامها الأساسي إلى الهندسة والعلوم. فالحسابات العددية السريعة والمرنة والمتطورة محور أساسي في تصميمها.
العدد الصحيح هو عدد "كامل" لا يحتوي على فاصلة عشرية.
في مفهوم الأساسيات، رأينا أنه يمكن إسناد قيمة عدد صحيح إلى متغير دون تحديد نوعه.
ولتحسين القراءة، يمكن استخدام الشرطات السفلية فاصلًا بين الأرقام. ويتجاهلها المُصرِّف.
julia> x = 3
3
julia> typeof(x)
Int64
julia> large_number = 1_234_567_890
1234567890
لن يفاجئك أن الأعداد العشرية تحتوي على فاصلة عشرية وجزء كسري بعدها.
julia> f = 3.45
3.45
julia> typeof(f)
Float64
وبالطبع، يُدعم الترميز العلمي.
julia> avogadro = 6.02e23
6.02e23
قد تفاجئك القيمتان العظمى والصغرى:
julia> typemax(Float64)
Inf
julia> typemin(Float64)
-Inf
اللانهاية قيمة صالحة!
كما ناقشنا في مفهوم الأساسيات، تعمل العوامل الحسابية في الغالب مثل الحساب المعتاد كما يُعلَّم للأطفال.
لاحظ أن الرفع إلى قوة يستخدم ^، وليس ** (وكلاهما شائع في لغات أخرى).
2 + 3 # 5 (addition)
2 - 3 # -1 (subtraction)
2 * 3 # 6 (multiplication)
8 / 2 # 4.0 (division)
8 % 3 # 2 (remainder)
2 ^ 3 # 8 (exponentiation)
لكن هناك بعض التفاصيل الخاصة بـ Julia التي تستحق الحديث عنها.
julia> x = 4.2
4.2
julia> 2 * x
8.4
julia> 2x
8.4
julia> 2.4x
10.08
قد يكون هذا مفاجئًا.
يمكنك دائمًا استخدام * كعامل إقحامي، كما في معظم لغات البرمجة الأخرى.
غير أن Julia صمّمها أشخاص يؤمنون بأن الكود ينبغي أن يشبه المعادلات الرياضية قدر الإمكان.
ولأن أسماء المتغيرات يجب أن تبدأ بحرف، فإن وضع رقم (صحيح أو عشري) قبل الاسم يُعالج كضرب ضمني.
على سبيل المثال، إذا أردنا مساحة سطح كرة، فبدلًا من 4 * pi * r * r يمكننا أن نفعل هذا:
julia> surface(r) = 4π * r^2
surface (generic function with 1 method)
julia> surface(3)
113.09733552923255
مع أن π ثابت مدمج، فهو أيضًا حرف (يوناني).
لذلك لا يزال المحلِّل بحاجة إلى * صريح واحد للفصل بين π و r.
استخدام / كعامل إقحامي يعطي دائمًا نتيجة عشرية، حتى مع مدخلات صحيحة.
أما القسمة الصحيحة، فلها خيارات أكثر.
julia> 10 / 3 # floating-point division
3.3333333333333335
julia> div(10, 3) # integer division
3
julia> 10 ÷ 3 # synonym for div()
3
julia> 10 // 3 # rational number (fraction)
10//3
دالة div() مخصصة للقسمة الصحيحة، وتُقتطع نتيجتها نحو الصفر: إلى الأسفل مع الأعداد الموجبة، وإلى الأعلى مع الأعداد السالبة.
وكمرادف، يمكننا استخدام العامل الإقحامي ÷، مرة أخرى بهدف جعله يبدو أكثر رياضية.
وإذا كنت تستخدم محررًا يدعم Julia، فأدخل \div ثم اضغط مفتاح <Tab>.
عامل // خارج نطاق هذا المفهوم.
وفي الوقت الحالي، يمكننا القول فقط إن نتيجة // عدد "نسبي"، وهو ما يسميه معظم الناس كسرًا.
غالبًا ما يحدث هذا تلقائيًا:
julia> x = 2 + 3.5
5.5
julia> typeof(x)
Float64
أضفنا Int64 إلى Float64، فحصلنا على نتيجة Float64.
في الواقع، حُوِّل العدد الصحيح بصمت إلى Float64 قبل إجراء الجمع.
إن التحويلات من عدد عشري إلى عدد صحيح لا بد أن تكون أكثر تعقيدًا. فماذا تريد أن تفعل بأي شيء يقع بعد الفاصلة العشرية؟
round() تحوّل إلى أقرب عدد صحيح، وعند التعادل مثل 4.5 تُقرَّب إلى أقرب عدد صحيح زوجي.floor() تُقرّب للأسفل، وceil() تُقرّب للأعلى، وtrunc() تُقرّب نحو الصفر.Int32()، ستفشل بخطأ InexactError.لكن افتراضيًا، لا تُرجع هذه الدوال نوع العدد الصحيح الذي قد تكون أردته. ويمكن تحديد نوع الإخراج المطلوب.
julia> round(4.5)
4.0
julia> ceil(Int, 4.3)
5
ويمكن أيضًا التقريب إلى عدد محدد من الأرقام بعد الفاصلة العشرية باستخدام الكلمة المفتاحية digits.
julia> round(π, digits=10)
3.1415926536
ألا يؤدي هذا ببساطة إلى خطأ؟ في الواقع، الأمر ليس بهذه البساطة.
القسمة الصحيحة باستخدام ÷ أو // ستؤدي إلى خطأ، كما قد تتوقع.
أما القسمة العشرية باستخدام / فتتبع نهجًا قد يُعتبر هندسيًا، لا نهج علوم الحاسوب المعتاد:
julia> 2 / 0
Inf
julia> 0 / 0
NaN
كما ناقشنا في قسم سابق، اللانهاية عدد عشري صالح في Julia، ويُمثَّل بـ Inf.
وعندما يكون البسط صفرًا أيضًا، تكون النتيجة غير معرّفة رياضيًا.
حينها تتعامل معها Julia على أنها "ليست عددًا"، ويُمثَّل ذلك بـ NaN.
يخطط صديقك Chandler لزيارة بلدان بعيدة وغريبة في أنحاء العالم. ولسوء الحظ، مهارات Chandler في الرياضيات ليست جيدة. وهو قلق جدًا من أن يتعرض للاحتيال في محلات صرف العملات أثناء رحلته، ويريد منك أن تصنع له حاسبة عملات. وهذه هي مواصفاته للتطبيق:
أنشئ الدالة exchange_money()، وهي تأخذ معاملين اثنين:
budget : المبلغ المالي الذي تخطط لصرفه.exchange_rate : مقدار العملة المحلية الذي يعادل وحدة واحدة من العملة الأجنبية.يجب أن تُرجع هذه الدالة قيمة العملة بعد صرفها.
ملاحظة: إذا كانت عملتك هي الدولار الأمريكي وأردت صرف الدولار مقابل اليورو بسعر صرف قدره 1.20، فإن 1.20 USD == 1 EUR.
julia> exchange_money(127.5, 1.2)
106.25
أنشئ الدالة get_change()، وهي تأخذ معاملين اثنين:
budget : المبلغ المالي قبل الصرف.exchanging_value : المبلغ المالي الذي يُخصم من الميزانية ليتم صرفه.يجب أن تُرجع هذه الدالة المبلغ المالي المتبقي من الميزانية.
julia> get_change(127.5, 120)
7.5
أنشئ الدالة get_value_of_bills()، وهي تأخذ معاملين اثنين:
denomination : قيمة الورقة النقدية الواحدة.number_of_bills : العدد الإجمالي للأوراق النقدية.لا يتعامل كشك الصرف هذا إلا بنقود ذات مضاعفات محددة. يجب أن يكون المبلغ الإجمالي الذي تحصل عليه قابلًا للقسمة على قيمة «الورقة» الواحدة أو الوحدة، وقد يتبقى كسر أو باقٍ. يجب أن تُرجع دالتك قيمة الأوراق النقدية الإجمالية فقط (باستثناء الكسور) التي سيعيدها الكشك. ولسوء الحظ، يحتفظ الكشك بالباقي/الفكة لنفسه كمكافأة إضافية.
julia> get_value_of_bills(5, 128)
640
أنشئ الدالة get_number_of_bills()، وهي تأخذ amount وdenomination.
يجب أن تُرجع هذه الدالة عدد الأوراق النقدية التي يمكنك الحصول عليها ضمن المبلغ المعطى. بعبارة أخرى: كم عدد الأوراق النقدية الكاملة التي تدخل في المبلغ الابتدائي؟ تذكّر أنك لا تستطيع الحصول إلا على أوراق نقدية كاملة، لا على كسور منها، فاحرص على القسمة وفقًا لذلك. وبذلك فأنت تقرّب إلى الأسفل إلى أقرب ورقة/فئة نقدية كاملة.
julia> get_number_of_bills(127.5, 5)
25
أنشئ الدالة get_leftover_of_bills()، وهي تأخذ amount وdenomination.
يجب أن تُرجع هذه الدالة المبلغ المتبقي الذي لا يمكن إعادته من المبلغ الابتدائي بالنظر إلى فئة الأوراق النقدية. ومن المهم جدًا معرفة المبلغ الذي يحتفظ به الكشك بدقة.
julia> get_leftover_of_bills(127.5, 20)
7.5
أنشئ الدالة exchangeable_value()، وهي تأخذ budget وexchange_rate وspread وdenomination.
المعامل spread هو النسبة المئوية المخصومة كرسوم صرف، ويُكتب على هيئة عدد صحيح.
ويجب تحويله إلى عدد عشري بقسمته على 100.
إذا كان 1.00 EUR == 1.20 USD وكان spread يساوي 10، فسيصبح سعر الصرف الإجمالي في الواقع: 1.00 EUR == 1.32 USD، لأن 10% من 1.20 تساوي 0.12، وتُضاف هذه الرسوم الإضافية إلى الصرف.
يجب أن تُرجع هذه الدالة القيمة القصوى للعملة الجديدة بعد حساب سعر الصرف مضافًا إليه spread. تذكّر أن فئة العملة عدد صحيح، ولا يمكن تجزئتها.
ملاحظة: يجب أن تكون القيمة المُرجَعة من نوع عدد صحيح.
julia> exchangeable_value(127.25, 1.20, 10, 20)
80
julia> exchangeable_value(127.25, 1.20, 10, 5)
95
سجّل في Exercism لتتعلّم وتتقن Julia عبر 35 مفهومًا128 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.