كيفية تقريب الأرقام لأعلى أو لأسفل أو لأقرب قيمة

التحكم في كيفية تقريب جافا سكريبت للأرقام العشرية عند التنسيق باستخدام أوضاع تقريب مختلفة

مقدمة

عندما تقوم بتنسيق الأرقام للعرض، غالبًا ما تحتاج إلى تقريب القيم العشرية. فسعر 2.567$ يجب أن يصبح 2.57$. وقياس 3.891 متر قد يُعرض كـ 4 أمتار. الطريقة التي تقرب بها هذه الأرقام تؤثر على الدقة وتوقعات المستخدم ومنطق العمل.

تتطلب المواقف المختلفة استراتيجيات تقريب مختلفة. أحيانًا تحتاج إلى التقريب لأعلى لضمان فرض رسوم كافية على منتج ما. وأحيانًا تحتاج إلى التقريب لأسفل للبقاء ضمن الميزانية. وفي معظم الأحيان، تقوم بالتقريب إلى أقرب قيمة للحفاظ على الدقة.

توفر جافا سكريبت تسعة أوضاع تقريب مختلفة من خلال واجهة برمجة التطبيقات Intl.NumberFormat. تتحكم هذه الأوضاع في كيفية تقريب الأرقام عندما تقع بين قيمتين محتملتين. يشرح هذا الدرس أكثر ثلاثة أوضاع تقريب شيوعًا ويوضح متى تستخدم الأوضاع الأخرى.

كيف تقرب جافا سكريبت الأرقام افتراضيًا

عندما تقوم بتنسيق رقم دون تحديد وضع التقريب، تستخدم جافا سكريبت استراتيجية تسمى halfExpand. يقرب هذا الوضع القيم إلى أقرب قيمة ممكنة، وعندما يقع الرقم بالضبط في منتصف المسافة بين قيمتين، فإنه يقرب بعيدًا عن الصفر.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0
});

console.log(formatter.format(2.4));
// الناتج: "2"

console.log(formatter.format(2.5));
// الناتج: "3"

console.log(formatter.format(2.6));
// الناتج: "3"

القيمة 2.4 أقرب إلى 2 منها إلى 3، لذلك يتم تقريبها لأسفل إلى 2. القيمة 2.6 أقرب إلى 3 منها إلى 2، لذلك يتم تقريبها لأعلى إلى 3. القيمة 2.5 تقع بالضبط في منتصف المسافة بين 2 و3، لذلك فإن وضع halfExpand يقربها بعيدًا عن الصفر إلى 3.

يتطابق هذا السلوك الافتراضي مع ما يتعلمه معظم الناس في المدرسة ويتوقعونه في الحسابات اليومية. وهو يوزع أخطاء التقريب بالتساوي على العديد من العمليات الحسابية، مما يجعله مناسبًا لتنسيق الأرقام للأغراض العامة.

فهم معنى "البعد عن الصفر"

تصف عبارة "البعد عن الصفر" اتجاه التقريب للأرقام التي تقع بالضبط في منتصف المسافة بين قيمتين محتملتين. بالنسبة للأرقام الموجبة، التقريب بعيدًا عن الصفر يعني التقريب لأعلى. بالنسبة للأرقام السالبة، التقريب بعيدًا عن الصفر يعني التقريب لأسفل إلى قيمة مطلقة أكبر.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0
});

console.log(formatter.format(2.5));
// Output: "3"

console.log(formatter.format(-2.5));
// Output: "-3"

كل من 2.5 و -2.5 يتم تقريبهما بعيدًا عن الصفر. بالنسبة لـ 2.5، البعد عن الصفر يعني الاتجاه نحو ما لا نهاية موجبة، مما ينتج عنه 3. بالنسبة لـ -2.5، البعد عن الصفر يعني الاتجاه نحو ما لا نهاية سالبة، مما ينتج عنه -3. في كلتا الحالتين، تزداد القيمة المطلقة.

التقريب لأعلى باستخدام ceil

وضع التقريب ceil يقرب دائمًا نحو ما لا نهاية موجبة. بالنسبة للأرقام الموجبة، هذا يعني التقريب لأعلى. بالنسبة للأرقام السالبة، هذا يعني التقريب نحو الصفر.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0,
  roundingMode: "ceil"
});

console.log(formatter.format(2.1));
// Output: "3"

console.log(formatter.format(2.9));
// Output: "3"

console.log(formatter.format(-2.1));
// Output: "-2"

console.log(formatter.format(-2.9));
// Output: "-2"

هذا الوضع مفيد عندما تحتاج إلى ضمان أن الرقم لن يكون أبدًا أصغر من اللازم. على سبيل المثال، إذا حسبت أن الصندوق يمكن أن يحتوي على 2.3 عنصر، فأنت بحاجة إلى 3 صناديق. إذا حسبت أن المهمة تستغرق 1.1 يوم، فأنت بحاجة إلى التخطيط لمدة يومين.

const boxFormatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0,
  roundingMode: "ceil"
});

const itemsPerBox = 5;
const totalItems = 12;
const boxesNeeded = totalItems / itemsPerBox;

console.log(boxFormatter.format(boxesNeeded));
// Output: "3"

ينتج عن الحساب 2.4 صندوق، لكن لا يمكنك طلب جزء من صندوق. التقريب لأعلى يضمن أن لديك سعة كافية.

التقريب لأسفل باستخدام floor

وضع التقريب floor يقرب دائمًا باتجاه سالب ما لا نهاية. بالنسبة للأرقام الموجبة، هذا يعني التقريب لأسفل. بالنسبة للأرقام السالبة، هذا يعني التقريب بعيدًا عن الصفر.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0,
  roundingMode: "floor"
});

console.log(formatter.format(2.1));
// Output: "2"

console.log(formatter.format(2.9));
// Output: "2"

console.log(formatter.format(-2.1));
// Output: "-3"

console.log(formatter.format(-2.9));
// Output: "-3"

هذا الوضع مفيد عندما تحتاج إلى تقديرات متحفظة أو عندما تريد البقاء ضمن الحدود. على سبيل المثال، إذا كان لديك ميزانية قدرها 100.87 دولار، فقد تعرضها كـ 100 دولار لتجنب الإنفاق الزائد عن غير قصد.

const budgetFormatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  maximumFractionDigits: 0,
  roundingMode: "floor"
});

const availableBudget = 100.87;

console.log(budgetFormatter.format(availableBudget));
// Output: "$100"

التقريب لأسفل يضمن أن المبلغ المعروض يمكن تحقيقه دائمًا بالميزانية الفعلية.

التقريب لأقرب قيمة باستخدام halfExpand

بينما يعتبر halfExpand هو الوضع الافتراضي، يمكنك تحديده صراحةً لجعل قصدك واضحًا في الكود. يقوم هذا الوضع بالتقريب إلى أقرب قيمة ويتعامل مع الحالات المتوسطة عن طريق التقريب بعيدًا عن الصفر.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 1,
  roundingMode: "halfExpand"
});

console.log(formatter.format(2.14));
// Output: "2.1"

console.log(formatter.format(2.15));
// Output: "2.2"

console.log(formatter.format(2.16));
// Output: "2.2"

القيمة 2.14 أقرب إلى 2.1، لذلك يتم تقريبها إلى 2.1. القيمة 2.16 أقرب إلى 2.2، لذلك يتم تقريبها إلى 2.2. القيمة 2.15 تقع بالضبط في المنتصف، لذلك يتم تقريبها بعيدًا عن الصفر إلى 2.2.

يعمل هذا الوضع بشكل جيد لمعظم مهام تنسيق الأرقام لأنه يقلل من إجمالي خطأ التقريب عبر العديد من العمليات الحسابية. كل قيمة متوسطة لديها فرصة متساوية لأن تكون على الجانب الموجب أو السالب من الصفر، لذلك يتوازن اتجاه التقريب مع مرور الوقت.

دمج أوضاع التقريب مع الأرقام العشرية

تعمل أوضاع التقريب جنبًا إلى جنب مع إعدادات الأرقام العشرية للتحكم في المخرجات النهائية. يحدد خيار maximumFractionDigits عدد المنازل العشرية التي تظهر، ويحدد roundingMode كيفية التعامل مع القيم التي تقع بين الأرقام القابلة للتمثيل.

const ceilFormatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  minimumFractionDigits: 2,
  maximumFractionDigits: 2,
  roundingMode: "ceil"
});

console.log(ceilFormatter.format(10.001));
// Output: "$10.01"

console.log(ceilFormatter.format(10.999));
// Output: "$11.00"

مع منزلتين عشريتين، يجب تقريب 10.001 إما إلى 10.00 أو 10.01. يقوم وضع ceil بالتقريب لأعلى، مما ينتج عنه 10.01. أما القيمة 10.999 فيتم تقريبها لأعلى إلى 11.00.

التقريب نحو الصفر باستخدام trunc

وضع التقريب trunc يقرب نحو الصفر، مما يعني أنه يزيل الجزء الكسري من الرقم. بالنسبة للأرقام الموجبة، فإن هذا يقرب لأسفل. وبالنسبة للأرقام السالبة، فإن هذا يقرب لأعلى.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0,
  roundingMode: "trunc"
});

console.log(formatter.format(2.1));
// Output: "2"

console.log(formatter.format(2.9));
// Output: "2"

console.log(formatter.format(-2.1));
// Output: "-2"

console.log(formatter.format(-2.9));
// Output: "-2"

يقوم هذا الوضع فعليًا باقتطاع الجزء العشري. وهو مفيد عندما تريد إظهار الجزء الصحيح فقط من الرقم دون النظر إلى القيمة الكسرية لأغراض التقريب.

التقريب بعيدًا عن الصفر باستخدام expand

وضع التقريب expand يقرب بعيدًا عن الصفر. بالنسبة للأرقام الموجبة، فإن هذا يقرب لأعلى. وبالنسبة للأرقام السالبة، فإن هذا يقرب لأسفل إلى قيمة مطلقة أكبر.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0,
  roundingMode: "expand"
});

console.log(formatter.format(2.1));
// Output: "3"

console.log(formatter.format(2.9));
// Output: "3"

console.log(formatter.format(-2.1));
// Output: "-3"

console.log(formatter.format(-2.9));
// Output: "-3"

يضمن هذا الوضع أن التقريب يزيد دائمًا من القيمة المطلقة للرقم. يمكن أن يكون مفيدًا في السياقات المالية حيث تريد أن تكون متحفظًا في اتجاه يفضل الدقة على التقدير المنخفض.

فهم أوضاع التقريب النصفي

الأوضاع الخمسة التي تبدأ بـ half تقوم جميعها بالتقريب إلى أقرب قيمة، لكنها تختلف في كيفية التعامل مع حالات المنتصف بالضبط. توفر هذه الأوضاع تحكمًا دقيقًا في سلوك كسر التعادل عندما تقع القيم بالضبط بين رقمين قابلين للتمثيل.

وضع halfCeil يقرب قيم المنتصف نحو ما لا نهاية موجبة.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0,
  roundingMode: "halfCeil"
});

console.log(formatter.format(2.5));
// Output: "3"

console.log(formatter.format(-2.5));
// Output: "-2"

وضع halfFloor يقرب قيم المنتصف نحو ما لا نهاية سالبة.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0,
  roundingMode: "halfFloor"
});

console.log(formatter.format(2.5));
// Output: "2"

console.log(formatter.format(-2.5));
// Output: "-3"

وضع halfTrunc يقرب قيم المنتصف نحو الصفر.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0,
  roundingMode: "halfTrunc"
});

console.log(formatter.format(2.5));
// Output: "2"

console.log(formatter.format(-2.5));
// Output: "-2"

وضع halfEven يقرب قيم المنتصف إلى أقرب رقم زوجي. يُطلق على هذا الوضع أحيانًا تقريب المصرفيين لأنه يقلل التحيز في الحسابات المالية.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 0,
  roundingMode: "halfEven"
});

console.log(formatter.format(2.5));
// Output: "2"

console.log(formatter.format(3.5));
// Output: "4"

console.log(formatter.format(4.5));
// Output: "4"

القيمة 2.5 تُقرب إلى 2 لأن 2 رقم زوجي. القيمة 3.5 تُقرب إلى 4 لأن 4 رقم زوجي. القيمة 4.5 تُقرب أيضًا إلى 4 لأن 4 رقم زوجي.

اختيار وضع التقريب لتطبيقك

يعتمد وضع التقريب الذي تختاره على متطلبات عملك وطبيعة البيانات التي تعرضها. تتطلب السياقات المختلفة استراتيجيات مختلفة.

استخدم ceil عندما تحتاج إلى ضمان الكفاية. غالبًا ما تتطلب تخطيط السعة وعد المخزون وتقديرات الوقت التقريب لأعلى لضمان الموارد الكافية.

استخدم floor عندما تحتاج إلى البقاء ضمن الحدود. غالبًا ما تتطلب عروض الميزانية وتتبع الحصص وحسابات الخصم التقريب لأسفل لتجنب تجاوز الموارد المتاحة.

استخدم halfExpand للعرض العام حيث تهم الدقة ولكن الدقة المفرطة ليست حاسمة. هذا هو الوضع الافتراضي لسبب ما ويعمل بشكل جيد لمعظم مهام تنسيق الأرقام.

استخدم halfEven للحسابات المالية حيث تحتاج إلى تقليل تحيز التقريب التراكمي. يضمن هذا الوضع أنه، على مدار العديد من الحسابات، لا تفضل أخطاء التقريب باستمرار اتجاهًا واحدًا.

استخدم trunc عندما تريد عرض الجزء الصحيح فقط من الرقم دون تطبيق منطق التقريب على الجزء الكسري.

استخدام أوضاع التقريب مع تنسيق العملات

تتفاعل أوضاع التقريب بشكل طبيعي مع تنسيق العملات. تمتلك الشركات المختلفة قواعد مختلفة حول كيفية تقريب قيم العملات، ويتيح لك خيار roundingMode تنفيذ تلك القواعد.

const retailPrice = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  minimumFractionDigits: 2,
  maximumFractionDigits: 2,
  roundingMode: "ceil"
});

const wholesalePrice = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  minimumFractionDigits: 2,
  maximumFractionDigits: 2,
  roundingMode: "floor"
});

const calculatedPrice = 19.874;

console.log(retailPrice.format(calculatedPrice));
// Output: "$19.88"

console.log(wholesalePrice.format(calculatedPrice));
// Output: "$19.87"

قد يقوم بائع التجزئة بتقريب الأسعار لأعلى لضمان الربحية، بينما قد يقوم تاجر الجملة بالتقريب لأسفل للبقاء منافسًا. ينتج عن نفس السعر المحسوب قيم عرض مختلفة بناءً على قواعد العمل المشفرة في وضع التقريب.