عدد به حروف

نوشتن عدد صحیح با حروف فارسی (تا 10^21) و خواندن دوبارهٔ عدد از روی حروف با fromWords(). عدد به حروف عربی در صفحهٔ جدا توضیح داده شده است.

در این صفحه
  1. عدد به حروف
    1. ورودی قابل قبول
    2. خطاها
  2. عربی
  3. از حروف به عدد
    1. متن چطور خوانده می‌شود

عدد به حروف#

NumberToWords::convert() یک عدد صحیح را با حروف می‌نویسد. زبان پیش‌فرض فارسی (fa) است و هر عدد صحیح کوچک‌تر از 1021 را پوشش می‌دهد.

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

use RtlyKit\Number\NumberToWords;
use function RtlyKit\number_to_words;

echo NumberToWords::convert(0), "\n";        // صفر
echo NumberToWords::convert(21), "\n";       // بیست و یک
echo NumberToWords::convert(115), "\n";      // صد و پانزده
echo NumberToWords::convert(1001), "\n";     // یک هزار و یک
echo NumberToWords::convert(12345), "\n";    // دوازده هزار و سیصد و چهل و پنج
echo NumberToWords::convert(-45), "\n";      // منفی چهل و پنج
echo number_to_words(2000000000), "\n";      // دو میلیارد
echo NumberToWords::convert(1234567), "\n";
// یک میلیون و دویست و سی و چهار هزار و پانصد و شصت و هفت

بخش‌ها با «و» به هم وصل می‌شوند و بعد از هر گروه نام مقیاس می‌آید: هزار (103)، میلیون (106)، میلیارد (109)، تریلیون (1012)، کوادریلیون (1015) و کوینتیلیون (1018). اگر گروهی ۱ باشد، «یک» نوشته می‌شود (۱۰۰۰ می‌شود «یک هزار»). گروه‌های صفر نوشته نمی‌شوند.

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

نوع ورودی int|float|string است:

  • int: کل بازهٔ PHP، از جمله PHP_INT_MAX، کار می‌کند.
  • float: باید متناهی و صحیح باشد. 3.0 می‌شود «سه». برای 1.5 خطا می‌گیرید و اعشار بی‌صدا بریده نمی‌شود.
  • string: علامت اختیاری و رقم‌هایی از هر دسته. ویرگول، ٬ و فاصله حذف می‌شوند، پس عددی که از فرم کپی شده هم کار می‌کند. رشته می‌تواند از بزرگ‌ترین int پی‌اچ‌پی هم بلندتر باشد: تا ۲۱ رقم، بعد از حذف صفرهای اول.
echo NumberToWords::convert('۱۲۳٬۴۵۶'), "\n";        // صد و بیست و سه هزار و چهارصد و پنجاه و شش
echo NumberToWords::convert('1,000,000'), "\n";      // یک میلیون
echo NumberToWords::convert('+7'), "\n";             // هفت
echo NumberToWords::convert('-0'), "\n";             // صفر
echo NumberToWords::convert('999999999999999999999'), "\n";
// نهصد و نود و نه کوینتیلیون و نهصد و نود و نه کوادریلیون ... و نهصد و نود و نه

خطاها#

ورودی نامعتبر InvalidNumberException (زیرکلاس RtlyKitException) می‌دهد. کد پایدارش را با getErrorCode() بخوانید:

ورودیکد خطا
1.5، '12a'، ''invalid_number
NAN، INFnon_finite_number
رشته‌ای بلندتر از ۴۰۹۶ بایتinput_too_long
1e21، '1000000000000000000000' (۲۲ رقم)number_too_large
try {
    NumberToWords::convert('1000000000000000000000');
} catch (\RtlyKit\Exceptions\InvalidNumberException $e) {
    echo $e->getMessage(), ' [', $e->getErrorCode()->value, "]\n";
    // Number is too large (limit is 10^21 - 1). [number_too_large]
}

برای گرفتن همهٔ خطاهای کتابخانه با یک نوع، مدیریت خطا را ببینید.

عربی#

با آرگومان دوم 'ar' عدد به عربی فصیح نوشته می‌شود. زبان با دو حرف اول و بدون توجه به بزرگی و کوچکی حرف‌ها تشخیص داده می‌شود، پس 'ar_SA' و 'AR' هم کار می‌کنند (برای فارسی هم 'fa_IR').

echo NumberToWords::convert(11, 'ar'), "\n";        // أحد عشر
echo NumberToWords::convert(21, 'ar'), "\n";        // واحد وعشرون
echo NumberToWords::convert(200, 'ar'), "\n";       // مئتان
echo NumberToWords::convert(3000, 'ar'), "\n";      // ثلاثة آلاف
echo NumberToWords::convert(2000000, 'ar'), "\n";   // مليونان
echo NumberToWords::convert(1002003, 'ar'), "\n";   // مليون وألفان وثلاثة
echo NumberToWords::convert(-7, 'ar'), "\n";        // سالب سبعة

در عربی هر عدد صحیح کوچک‌تر از 1027 پشتیبانی می‌شود. جنس معدود، حالت اعرابی، اعراب‌گذاری و عدد ترتیبی ۱ تا ۹۹ هم هست. همهٔ این گزینه‌ها در صفحهٔ عدد به حروف عربی آمده است.

اگر زبان پشتیبانی نشود، UnsupportedLocaleException با کد unsupported_locale می‌گیرید:

try {
    NumberToWords::convert(5, 'en');
} catch (\RtlyKit\Exceptions\UnsupportedLocaleException $e) {
    echo $e->getMessage(), "\n";   // Unsupported locale 'en' (use 'fa' or 'ar').
}

از حروف به عدد#

NumberToWords::fromWords() کار برعکس convert() را برای متن فارسی می‌کند. اگر عدد در int پی‌اچ‌پی جا شود، int می‌دهد. وگرنه رشته‌ای از رقم‌ها.

var_dump(NumberToWords::fromWords('بیست و سه'));                 // int(23)
var_dump(NumberToWords::fromWords('منفی چهل و دو'));             // int(-42)
var_dump(NumberToWords::fromWords('هزار و یک'));                 // int(1001)
var_dump(NumberToWords::fromWords('دو میلیون و سیصد هزار و پنج')); // int(2300005)

// رفت‌وبرگشت در کل بازه:
var_dump(NumberToWords::fromWords(NumberToWords::convert(PHP_INT_MAX)));
// int(9223372036854775807)
var_dump(NumberToWords::fromWords(NumberToWords::convert('999999999999999999999')));
// string(21) "999999999999999999999"

متن چطور خوانده می‌شود#

  • اول متن یکسان می‌شود. حرف‌های عربی فارسی می‌شوند («ك» به «ک» و «ي» به «ی»)، نیم‌فاصله مثل فاصله حساب می‌شود و فاصله‌های اضافه نادیده گرفته می‌شود.
  • «منفی» در ابتدا عدد را منفی می‌کند. «منفی صفر» همان 0 است.
  • اگر قبل از نام مقیاس عددی نباشد، یعنی یک. پس «هزار» همان ۱۰۰۰ است.
  • مقیاس‌ها باید از بزرگ به کوچک بیایند. «هزار هزار» یا «هزار میلیون» خطا می‌دهد.
  • در هر گروه، اول صدگان می‌آید، بعد دهگان، بعد یکان. یا یک واژه از «ده» تا «نوزده» به‌جای دهگان و یکان. «دو صد»، «پنج و بیست» و «یازده و یک» خطا می‌دهند.
  • بین هر دو واژهٔ عددی «و» لازم است. فقط بین ضریب و نام مقیاس، مثل «دو هزار»، «و» نمی‌آید. «و» در ابتدا، در انتها، دو بار پشت هم، یا کنار نام مقیاس قبول نمی‌شود.
  • «صفر» فقط تنها (یا بعد از «منفی») قبول می‌شود.
try {
    NumberToWords::fromWords('یکصد');
} catch (\RtlyKit\Exceptions\InvalidNumberException $e) {
    echo $e->getMessage(), ' [', $e->getErrorCode()->value, "]\n";
    // Unknown number word 'یکصد'. [invalid_number_words]
}

خطاها کد invalid_number_words دارند (واژهٔ ناشناخته، ترتیب غلط، مقیاس‌های نامرتب، متن خالی). برای متن بلندتر از ۴۰۹۶ بایت هم input_too_long می‌گیرید.

خواننده سخت‌گیر است. fromWords() فقط ترتیب استاندارد واژه‌ها را قبول می‌کند. عبارت‌هایی مثل «دو صد»، «بیست یک» یا «و»ی اضافه در آخر InvalidNumberException با کد invalid_number_words می‌دهند. هر متنی که convert() بسازد درست خوانده می‌شود. نام مقیاسِ تنها در ابتدا هم مجاز است («هزار و یک»). فقط فارسی خوانده می‌شود. واژه‌های عربی خروجی convert($n, 'ar') و ترتیبی‌هایی مثل «سی‌ام» خطا می‌دهند. املای چسبیدهٔ «یکصد» هم شناخته نمی‌شود.