رقم‌ها و قالب‌بندی عدد

تبدیل رقم‌های انگلیسی، فارسی و عربی-هندی به هم، قالب‌بندی عدد با جداکنندهٔ فارسی و ساختن عدد ترتیبی فارسی، با سقف‌ها و حالت‌های مرزی.

در این صفحه
  1. رقم‌ها
    1. convert()
  2. قالب‌بندی عدد
    1. ورودی قابل قبول
    2. جداکنندهٔ دلخواه
    3. اعشاری و دقت
    4. سقف اندازه
  3. عدد ترتیبی

رقم‌ها#

کلاس RtlyKit\Number\Digits بین سه دستهٔ رقم که در نرم‌افزارهای ایرانی دیده می‌شود تبدیل می‌کند: انگلیسی (0-9)، فارسی (۰-۹، از U+06F0 تا U+06F9) و عربی-هندی (٠-٩، از U+0660 تا U+0669). کارش فقط جایگزینی نویسه‌هاست. خطا پرتاب نمی‌کند، به نویسه‌های دیگر دست نمی‌زند و جداکنندهٔ اعشار و هزارگان را عوض نمی‌کند.

<?php
require 'vendor/autoload.php';

use RtlyKit\Number\Digits;

echo Digits::toPersian('Tel 0912 / 2024'), "\n";   // Tel ۰۹۱۲ / ۲۰۲۴
echo Digits::toPersian(1234.5), "\n";              // ۱۲۳۴.۵
echo Digits::toArabic(2026), "\n";                 // ٢٠٢٦
echo Digits::toEnglish('۱۲۳ ٤٥٦ abc'), "\n";        // 123 456 abc
echo Digits::arabicToPersian('٠١٢ 345'), "\n";      // ۰۱۲ 345
متدورودیکار
toPersian($value)رشته، int، floatرقم‌های انگلیسی را فارسی می‌کند. رقم‌های فارسی و عربی-هندی که از قبل در رشته هستند دست نمی‌خورند
toArabic($value)رشته، int، floatرقم‌های انگلیسی را عربی-هندی می‌کند
toEnglish($value)رشتهرقم‌های فارسی و عربی-هندی را انگلیسی می‌کند
arabicToPersian($value)رشتهفقط رقم‌های عربی-هندی را فارسی می‌کند. رقم‌های انگلیسی می‌مانند
convert($value, $to)رشتهاول همه‌چیز را انگلیسی می‌کند، بعد به دستهٔ مقصد می‌برد

convert()#

متد convert() اول رقم‌ها را انگلیسی می‌کند و بعد دستهٔ مقصد را می‌سازد. نام مقصد به بزرگی و کوچکی حرف حساس نیست. persian و fa و farsi رقم فارسی می‌دهند. arabic و ar رقم عربی-هندی می‌دهند. هر چیز دیگر، حتی غلط املایی، انگلیسی می‌دهد.

echo Digits::convert('۱۲۳', 'ar'), "\n";        // ١٢٣
echo Digits::convert('123', 'fa'), "\n";        // ۱۲۳
echo Digits::convert('٣٤٥', 'FARSI'), "\n";     // ۳۴۵
echo Digits::convert('۱۲۳', 'x'), "\n";         // 123
عدد به‌جای رشته. toPersian() و toArabic() int و float هم می‌گیرند. آن‌ها را با تبدیل ساده به رشته ((string)) می‌نویسند. برای همین ممیز اعشار همان نقطهٔ لاتین می‌ماند (۱۲۳۴.۵) و جداکنندهٔ هزارگان ندارد. برای عددی که کاربر می‌بیند، از Format::withSeparator() در ادامه استفاده کنید. توابع کمکی to_persian_digits()، to_english_digits()، to_persian() و to_english() همین متدها را صدا می‌زنند. توابع کمکی و سراسری را ببینید.

اعتبارسنج‌ها برای یکسان‌سازی از Digits::toEnglish() استفاده می‌کنند. پس کاربر با هر دستهٔ رقمی می‌تواند تایپ کند. یکسان‌سازی را ببینید.

قالب‌بندی عدد#

Format::withSeparator() عدد را با جداکنندهٔ هزارگان و رقم فارسی می‌نویسد. جداکنندهٔ هزارگان پیش‌فرض ٬ (U+066C) و ممیز اعشار ٫ (U+066B) است. این‌ها همان نویسه‌هایی هستند که تایپوگرافی فارسی پیشنهاد می‌کند. این متد گرد نمی‌کند.

use RtlyKit\Number\Format;

echo Format::withSeparator(1234567), "\n";            // ۱٬۲۳۴٬۵۶۷
echo Format::withSeparator('1,234,567.5'), "\n";      // ۱٬۲۳۴٬۵۶۷٫۵
echo Format::withSeparator('۱٬۲۳۴٫۵'), "\n";          // ۱٬۲۳۴٫۵
echo Format::withSeparator('0001234'), "\n";          // ۱٬۲۳۴
echo Format::withSeparator('+12345'), "\n";           // ۱۲٬۳۴۵
echo Format::withSeparator(1.0), "\n";                // ۱

ورودی قابل قبول#

  • int، float متناهی، یا رشتهٔ عددی با علامت اختیاری، رقم‌هایی از هر سه دسته و کسر اختیاری.
  • در رشته‌ها این‌ها به‌عنوان جداکنندهٔ گروه حذف می‌شوند: ,، ٬ (U+066C)، فاصلهٔ معمولی و فاصلهٔ بدون شکست. ممیز اعشار عربی ٫ (U+066B) و نقطهٔ . هر دو ممیز اعشار حساب می‌شوند.
  • صفرهای اول بخش صحیح و + اول حذف می‌شوند. - اول می‌ماند.

اگر بعد از این تمیزکاری چیزی عدد اعشاری ساده نباشد، InvalidNumberException می‌گیرید. مثل 'abc'، رشتهٔ خالی، نمای علمی در رشته ('1e5') و NaN یا INF. هر خطا یک کد پایدار دارد (invalid_number، non_finite_number، input_too_long) که با getErrorCode() می‌خوانید. مدیریت خطا را ببینید.

جداکنندهٔ دلخواه#

آرگومان دوم و سوم جداکنندهٔ هزارگان و اعشار را عوض می‌کنند. رقم‌ها باز هم فارسی می‌شوند:

echo Format::withSeparator(1234567, ','), "\n";            // ۱,۲۳۴,۵۶۷
echo Format::withSeparator(1234567.5, ',', '.'), "\n";     // ۱,۲۳۴,۵۶۷.۵

اگر رقم انگلیسی می‌خواهید، نتیجه را با Digits::toEnglish() برگردانید.

اعشاری و دقت#

float با کوتاه‌ترین متنی نوشته می‌شود که دوباره همان عدد را بدهد، به شرط اینکه از ۱۵ رقم معنادار بیشتر نشود. نمای علمی نمی‌آید و به تنظیمات php.ini هم بستگی ندارد. صفر منفی به شکل ۰ چاپ می‌شود. سقف ۱۵ رقم خطای دودویی را حذف می‌کند، پس 0.1 + 0.2 به شکل ۰٫۳ چاپ می‌شود. float بیشتر از حدود ۱۵ تا ۱۷ رقم معنادار نگه نمی‌دارد. اگر رقم بیشتری لازم دارید، رشته بدهید. رشته دقیق می‌ماند:

echo Format::withSeparator(-1234567.891), "\n";    // -۱٬۲۳۴٬۵۶۷٫۸۹۱
echo Format::withSeparator(0.1), "\n";             // ۰٫۱
echo Format::withSeparator(0.1 + 0.2), "\n";       // ۰٫۳
echo Format::withSeparator(1 / 3), "\n";           // ۰٫۳۳۳۳۳۳۳۳۳۳۳۳۳۳۳ (۱۵ رقم)
echo Format::withSeparator(123456789.123456789), "\n";     // ۱۲۳٬۴۵۶٬۷۸۹٫۱۲۳۴۵۷ (float)
echo Format::withSeparator('123456789.123456789'), "\n";   // ۱۲۳٬۴۵۶٬۷۸۹٫۱۲۳۴۵۶۷۸۹ (رشته، دقیق)
echo Format::withSeparator('0.3'), "\n";           // ۰٫۳
پول و عددهای بزرگ. مبلغ‌ها را از اول تا آخر به شکل رشته یا عدد صحیح (ریال) نگه دارید. float کسرها را دقیق نشان نمی‌دهد. دو مثال بالا (1 / 3 و 123456789.123456789) همین را نشان می‌دهند.

سقف اندازه#

سقفمربوط بهکد خطا
۴۰۹۶ بایترشتهٔ خام ورودی (هر رقم فارسی یا عربی دو بایت است)input_too_long
۱۰۰۰ نویسهعدد یکسان‌شده: رقم‌های بخش صحیح و کسر با همinput_too_long
try {
    Format::withSeparator(str_repeat('9', 1001));
} catch (\RtlyKit\Exceptions\InvalidNumberException $e) {
    echo $e->getMessage(), ' [', $e->getErrorCode()->value, "]\n";
    // Number exceeds the 1000 character limit. [input_too_long]
}

دقیقاً ۱۰۰۰ رقم مشکلی ندارد. همهٔ سقف‌ها در سقف‌ها یک‌جا آمده‌اند. تابع کمکی format_number() همان Format::withSeparator() با مقدارهای پیش‌فرض است.

عدد ترتیبی#

Format::ordinal() برای عدد صحیح نامنفی، واژهٔ ترتیبی فارسی می‌دهد. اول با NumberToWords عدد را به حروف می‌نویسد (عدد به حروف) و بعد پسوند را می‌گذارد:

  • ۱ استثناست و «اول» می‌شود.
  • عددی که آخرش «سه» باشد «سوم» می‌شود. ۲۳ و ۳۳ هم همین‌طور.
  • عددی که آخرش «ی» باشد (مثل «سی») نیم‌فاصله و «ام» می‌گیرد.
  • بقیه فقط «م» می‌گیرند.
echo Format::ordinal(1), "\n";     // اول
echo Format::ordinal(2), "\n";     // دوم
echo Format::ordinal(3), "\n";     // سوم
echo Format::ordinal(21), "\n";    // بیست و یکم
echo Format::ordinal(23), "\n";    // بیست و سوم
echo Format::ordinal(30), "\n";    // سی‌ام
echo Format::ordinal(33), "\n";    // سی و سوم
echo Format::ordinal(100), "\n";   // صدم
echo Format::ordinal(1000), "\n";  // یک هزارم
echo Format::ordinal(0), "\n";     // صفرم
echo Format::ordinal(3.0), "\n";   // سوم

عدد اعشاریِ صحیح مثل 3.0 قبول می‌شود. عدد منفی، کسر (2.5) و اعشاری نامتناهی InvalidNumberException می‌دهند (invalid_number، و برای INF و NaN کد non_finite_number). تابع کمکی آن ordinal() است.

واژه، نه رقم. ordinal() واژهٔ کامل را می‌دهد و شکل کوتاه عددی نمی‌سازد. اگر شکل کوتاه می‌خواهید، خودتان با Digits::toPersian() بسازید.