جولة Go التفاعلية بالعربي › تعليمات التحكم في التدفق: for وif وelse وswitch وتأجيل التنفيذ 3 / 7 السابق التالي

تمرين: الحلقات والدوال

تمرين: الحلقات والدوال

للتجريب بالدوال والحلقات، لننفّذ دالة لحساب الجذر التربيعي: إذا أُعطينا عددًا x، نريد إيجاد العدد z الذي تكون قيمة z² له أقرب ما يمكن إلى x.

تحسب الحواسيب عادةً الجذر التربيعي للعدد x باستخدام حلقة. انطلاقًا من قيمة تخمينية ما لـ z، يمكننا تعديل z بناءً على مدى قرب z² من x، لنحصل على تخمين أفضل:

z -= (z*z - x) / (2*z)

يؤدي تكرار هذا التعديل إلى تحسين التخمين أكثر فأكثر حتى نصل إلى إجابة قريبة من الجذر التربيعي الفعلي قدر الإمكان.

نفّذ ذلك في func Sqrt المُعطاة. يُعدّ العدد 1 تخمينًا أوليًا مناسبًا لـ z، مهما كانت قيمة المُدخل. في البداية، كرّر الحساب 10 مرات واطبع كل قيمة لـ z أثناء ذلك. لاحظ مدى اقترابك من الإجابة لقيم مختلفة من x (1، 2، 3، ...) ومدى سرعة تحسّن التخمين.

تلميح: للتصريح عن قيمة ذات فاصلة عائمة وتهيئتها، اكتبها بصيغة الفاصلة العائمة أو استخدم تحويلًا:

z := 1.0
z := float64(1)

بعد ذلك، غيّر شرط الحلقة بحيث تتوقف بمجرد أن تتوقف القيمة عن التغيّر (أو لا تتغيّر إلا بمقدار صغير جدًا). لاحظ ما إذا كان ذلك يستغرق أكثر من 10 تكرارات أم أقل. جرّب تخمينات أولية أخرى لـ z، مثل x أو x/2. ما مدى قرب نتائج دالتك من نتائج math.Sqrt في المكتبة القياسية؟

(ملاحظة: إذا كنت مهتمًا بتفاصيل الخوارزمية، فإن z² − x أعلاه هو مقدار ابتعاد z² عن القيمة التي ينبغي أن تكون عليها (x)، والقسمة على 2z هي المشتقة لـ z²، لضبط مقدار تعديلنا لـ z وفقًا لمدى سرعة تغيّر z². يُسمّى هذا النهج العام طريقة نيوتن. وهو يعمل جيدًا مع كثير من الدوال، لكنه يعمل جيدًا على نحو خاص مع الجذر التربيعي.)

النص الأصلي بالإنجليزية

Exercise: Loops and Functions

As a way to play with functions and loops, let's implement a square root function: given a number x, we want to find the number z for which z² is most nearly x.

Computers typically compute the square root of x using a loop. Starting with some guess z, we can adjust z based on how close z² is to x, producing a better guess:

z -= (z*z - x) / (2*z)

Repeating this adjustment makes the guess better and better until we reach an answer that is as close to the actual square root as can be.

Implement this in the func Sqrt provided. A decent starting guess for z is 1, no matter what the input. To begin with, repeat the calculation 10 times and print each z along the way. See how close you get to the answer for various values of x (1, 2, 3, ...) and how quickly the guess improves.

Hint: To declare and initialize a floating point value, give it floating point syntax or use a conversion:

z := 1.0
z := float64(1)

Next, change the loop condition to stop once the value has stopped changing (or only changes by a very small amount). See if that's more or fewer than 10 iterations. Try other initial guesses for z, like x, or x/2. How close are your function's results to the math.Sqrt in the standard library?

(Note: If you are interested in the details of the algorithm, the z² − x above is how far away z² is from where it needs to be (x), and the division by 2z is the derivative of z², to scale how much we adjust z by how quickly z² is changing. This general approach is called Newton's method. It works well for many functions but especially well for square root.)

هذا الدرس للقراءة فقط؛ جرّب المثال في الدرس التالي.

استعادة المثال الأصلي؟

ستُحذف تعديلاتك على شيفرة هذا الدرس، ويعود المثال كما ورد في الكتاب. لا يتغيّر اختيارك لمحرك التشغيل.