<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های سروش ربیعی</title>
        <link>https://virgool.io/feed/@gigtupus</link>
        <description>برنامه‌نویس سیستم / سی، سی‌پلاس‌پلاس / لینوکس</description>
        <language>fa</language>
        <pubDate>2026-06-10 15:25:20</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/12289/avatar/avatar.png?height=120&amp;width=120</url>
            <title>سروش ربیعی</title>
            <link>https://virgool.io/@gigtupus</link>
        </image>

                    <item>
                <title>درست‌نویسی متون دوجهته</title>
                <link>https://virgool.io/@gigtupus/how-to-write-unicode-bidi-djv7wowlkzte</link>
                <description>حتماً تا به‌حال براتون پیش اومده که وسط یه متن فارسی، یک متن انگلیسی می‌نویسید و همه‌چیز قاطی میشه. مخصوصاً توی محیط‌های Plain Text (یعنی محیط‌های متنی‌ای که شما کنترلی روی استایل و پاراگراف ندارید. مثل gedit یا kate یا مثلاً notepad توی ویندوز). خیلی زود متوجه خواهید شد که روش ساده‌ای برای نوشتن کاراکترهایی که به‌طور ذاتی راست‌به‌چپ هستن و یا چپ‌به‌راست نیستند، وجود نداره (در ادامه میگم که جهت یک کاراکتر یعنی چی). توی این پست می‌خوام روش استاندارد نوشتن متون دوطرفه رو معرفی کنم، و تأکید کنم که حتماً ازش استفاده کنید و هیچوقت به‌جای این‌کار از هک‌های متداول (مثل برعکس نوشتن ترتیب نویسه‌ها) استفاده نکنید چون این کار خیلی غلطه و متن شما رو از لحاظ محتوایی دچار ضعف می‌کنه. یعنی مثلا توی جستجوها متنی که خراب نوشتید پیدا نمیشه.صورت مسألهنویسه‌های یونیکد از لحاظ جهت‌گیری به چهار دستهٔ خنثی، راست‌به‌چپ، چپ‌به‌راست و ضعیف تقسیم‌بندی میشن. نویسه‌های چپ‌به‌راست نویسه‌هایی هستند که همیشه باید چپ‌به‌راست نمایش داده بشن. مثل حروف الفبای لاتین. نویسه‌های راست‌به‌چپ هم دقیقاً برعکس این‌ها هستند. مثل حروف الفبای عربی. یک دسته از نویسه‌ها هم هستند که جهت براشون معنی نداره. مثلاً نویسهٔ نوسطر یا نویسه‌هایی که دیده نمیشن (مثل نویسه‌های کنترلی) این‌ها نویسه‌های خنثی هستند. خوب تا این‌جا همه‌چیز خوب بود... مشکل بزرگ اما زمانی به‌وجود میاد که به نویسه‌های ضعیف برخورد می‌کنیم. نویسهٔ ضعیف نویسه‌ای هست که براساس جاگیری‌ش بین نویسه‌های دیگه می‌تونه راست‌به‌چپ یا چپ‌به‌راست باشه. مثل نویسهٔ + یا -  یا ( و ) و از این قبیل نشانه‌ها.خوب این نویسه‌های ضعیف متن رو خراب می‌کنن. چینش‌هایی از متن دوطرف وجود داره که از لحاظ منطقی الگوریتمی برای تعیین جهت یک سری نویسهٔ ضعیف توشون وجود نداره. مثلاً چطور؟ فرض کنید وسط یک متن فارسی بنویسم C++. همون‌طور که می‌بینید دو تا + رفتن به سمت چپ نویسهٔ C در حالی که منظور من اومدن اون‌ها به سمت راست بوده. در واقع من اول کلید C رو زدم، بعد دو بار کلید + رو فشار دادم. اما اگر جهت متن رو عوض کنم، یعنی توی این کد HTML یه تگ dir=ltr بنویسم، اونوقت نوشته‌های فارسی‌م در جهت‌های معکوس نشون داده میشن. برای این که مشکل رو (که قطعاً بهش برخورد کردید) مشاهده کنید؛ عکس‌های زیر رو ببینید:جهت نادرست متون انگلیسی میان فارسی و فارسی میان انگلیسیدر این عکس من این عبارت‌ها رو نوشتم: خط اول: «متن فارسی که در میان آن ‪C++‬ نوشته شده است.» خط دوم: « ‫Computer به وسیله‌ای گفته می‌شود که با آن Calculation انجام می‌دهند‬» (چقدر لوس!)ولی همون‌طور که ملاحظه می‌کنید نمایش متون درست نیست.اثبات می‌شود که الگوریتمی جامع برای کنترل جهت خودکار نویسه‌های ضعیف وجود ندارد. چون کاربر ممکنه هرکدوم از حالت‌ها مدنظرش باشه. برای همین؛ جهت اصلاح سوگیری نویسه‌ها؛ یک سری نویسه‌های کنترلی وجود داره. (نویسه‌هایی که شما اون‌ها رو نمی‌بینید ولی مثل یک کاراکتر معمولی هستند). با استفاده از این نویسه‌ها میشه خیلی راحت متن رو تنظیم کرد. طوری که متون راست‌به‌چپ وسط متون چپ‌به‌راست قاطی نشن و برعکس. درست مثل این عکس:جهت‌گیری درست نویسه‌ها در محیط دوجهتهبرای استفاده از این نویسه‌ها کافیه که متن خودتون رو بین یک جفت نویسهٔ کنترلی قرار بدید. برای این کار روش‌های مختلفی وجود داره. راحت‌ترین روش استفاده از صفحه‌کلید استاندارد فارسی هست که در انتها توضیح میدم چطوریه. اول باید بگم که چطور کار می‌کنه.طرز کار۱. اگر می‌خواهید وسط یک متن راست‌به‌چپ، یک متن چپ‌به‌راست بنویسید، یک نویسهٔ Left-to-Right Embedding (کد U+202A) قبل از متن چپ‌به‌راست و یک نویسهٔ Pop Directional Format (کد U+202C) بعد از متن چپ‌به‌راست قرار بدید.۲. اگر می‌خواهید وسط یک متن راست‌به‌چپ، یک متن چپ‌به‌راست بنویسید، یک نویسهٔ Right-to-Left Embedding (کد U+202B) قبل از متن چپ‌به‌راست و یک نویسهٔ Pop Directional Format (کد U+202C) بعد از متن چپ‌به‌راست قرار بدید.مثلاً عبارت «من ‪C++‬ هستم» به این صورت توی حافظه (به ترتیب از بالا به پایین) ذخیره میشه:0xd985 // ARABIC LETTER MEEM   م
0xd986 // ARABIC LETTER NOON   ن
0x0020 // SPACE   
0x8207 // LETF-TO-RIGHT EMBEDDING   
0x0067 // C
0x0043 // +
0x0043 // +
0x8236 // POP-DIRECTIONAL FORMAT
0x0020 // SPACE
0xd987 // ARABIC LETTER HEH   ه
0xd8b3 // ARABIC LETTER SEEN   س
0xd8aa // ARABIC LETTER TEH   ت
0xd985 // ARABIC LETTER MEEM   متایپ کردناگر صفحه‌کلید استاندارد فارسی استفاده می‌کنید کارتون خیلی راحته. (اگر کاربر یکی از توزیع‌های گنو/لینوکس باشید، صفحه‌کلید پیش‌فرض‌تون همین چینش صفحه‌کلید استاندارد خواهد بود.)برای درج نویسهٔ RLE از کلید Alt سمت راست به‌همراه ‪]‬ (چ فارسی) استفاده کنید.برای درج نویسهٔ LRE از کلید Alt سمت راست به‌همراه ‪[‬ (ج فارسی) استفاده کنیدبرای درج نویسهٔ PDF از کلید Alt سمت راست به‌همراه ‪P‬ (ح فارسی) استفاده کنیدبه همین راحتی! به یاد داشتن جای این کلیدها هم خیلی آسونه:جای کاراکترهای کنترلیاگر کاربر ویندوز هستید بهتره ویندوز رو پاک کنید و یه سیستم‌عامل آزاد نصب کنید. اگر رئیس‌تون این اجازه رو نمیده، می‌تونید چینش استاندارد فارسی برای ویندوز رو نصب کنید و البته فراموش نکنید که چینش احمقانهٔ من‌درآورُدیِ مایکروسافت رو هم غیرفعال کنید.یادداشتی برای توسعه‌دهندگان وب فارسی!معمولاً توسعه‌دهنده‌های وب وقتی می‌خوان یک متنی با جهت مخالف رو بین یک متن دیگه قرار بدن، دو  کار انجام میدن: یا کلاً بی‌خیال قضیه میشن و همه‌چیز به شکلی زشت و آزاردهنده دیده میشه، یا اینکه هک خودشون رو اختراع می‌کنن. در حالت دوم (هک) استفاده از تگ‌های &lt;span&gt; و بازنویسی جهت استفاده میشه. این خیلی بده! وقتی توی یک صفحهٔ HTML قرار باشه از متون دوجهته استفاده بشه، باید از همین روش بالا استفاده کنید. کدهای HTML برای نویسه‌های کنترلی این‌طوری هستند:برای درج نویسهٔ RLE از کد ‪&amp;#8207;‬ و یا بهتر از اون ‪&amp;rlm;‬ استفاده کنید.برای درج نویسهٔ LRE از کد ‪&amp;#8206;‬ و یا بهتر از اون ‪&amp;lrm;‬ استفاده کنید.برای درج نویسهٔ PDF از کد ‪&amp;#8236;‬ استفاده کنید.</description>
                <category>سروش ربیعی</category>
                <author>سروش ربیعی</author>
                <pubDate>Sun, 30 Jun 2019 21:54:59 +0430</pubDate>
            </item>
                    <item>
                <title>محاسبهٔ ثابت‌های ریاضی در ‪C++‬</title>
                <link>https://virgool.io/@gigtupus/cpp-constants-ekwh9mkew4pg</link>
                <description>هیچ‌کدام از استانداردهای سی‌پلاس‌پلاس و یا سی عدد π را تعریف نکرده‌اند. بنابراین هر برنامه‌نویسی که قصد داشته باشه از توابع مثلثاتی یا آماری استفاده کنه مجبوره خودش π رو تعریف کنه. خوشبختانه فایل‌های سرآیند استاندارد عدد π رو تعریف کرده‌اند، (ثابتM_PI در هدر math.h رو ببینید) با این وجود استفاده از این ثابت و ثابت‌های دیگه بسیار خطرناک هست و برای کاربردهای دقیق باعث بروز خطاهای عددی خواهد شد.خوشبختانه میشه با صرف هزینهٔ صفر در زمان اجرا π رو به‌صورت استاندارد (با تعاریف مشخص عددی) و البته در زمان کامپال محاسبه کرد. برای این کار از meta-programming به وسیلهٔ template ها در ‪C++‬ استفاده می‌کنیم. از مزایای این روش میشه به قابل حمل بودن و پیروی کامل از استاندارد IEEE 754 اشاره کرد که از لحاظ دقت عددی و یکسان بودن نتایج روی ماشین‌های مختلف بسیار مهم هست.برای محاسبهٔ عدد π روش‌های مختلفی وجود داره. اکثر این روش‌ها براساس محاسبهٔ یک سری یا دنباله هستند که در بینهایت به عدد پی همگرا میشه. یکی از بهترین روش‌ها فرمول Bailey–Borwein–Plouffe هست. اثبات میشه که:بنابراین با این کد توی ‪C++‬ می‌تونیم به‌سادگی عدد پی رو تا هر تعداد تکرار که میخواهیم حساب کنیم:#include &lt;cstdint&gt;
#include &lt;limits&gt;
#include &lt;iostream&gt;

template &lt;uint64_t b, uint64_t e&gt;
struct pow {
    static const uint64_t result = b * pow &lt; b, e - 1 &gt;::result;
};
template &lt;uint64_t b&gt; 
struct pow&lt;b, 0&gt; {
    static const uint64_t result = 1;
    };
template &lt;uint64_t n&gt;
struct bbp {
    constexpr static double pi
                = (1.0 / pow&lt;16, n&gt;::result)
                            * (   4.0 / (8 * n + 1.0) - 2.0 / (8 * n + 4.0)
                                - 1.0 / (8 * n + 5.0) - 1.0 / (8 * n + 6.0))
                                + bbp &lt; n - 1 &gt;::pi;
};
template &lt;&gt;
struct bbp &lt; -1 &gt; {
    constexpr static double pi = 0;
};
int main(int, char* []) {
    std::cout.precision(std::numeric_limits&lt;double&gt;::digits10);
    std::cout &lt;&lt; &quot;pi = &quot; &lt;&lt; bbp&lt;1&gt;::pi &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;pi = &quot; &lt;&lt; bbp&lt;5&gt;::pi &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;pi = &quot; &lt;&lt; bbp&lt;10&gt;::pi &lt;&lt; std::endl;
    return 0;
}نتایج:pi: 3.14142246642247
pi: 3.14159265322809
pi: 3.14159265358979
pi: 3.14159265358979چرا؟روش‌های زیادی برای محاسبهٔ عدد پی وجود داره. چرا دقیقاً این روش بهتره؟ مثلاً روش نیوتون به‌صورت هندسی عدد پی رو به این صورت حساب می‌کنه:روش نیوتون برای محاسبهٔ پی که نیازمند محاسبات سری پیوسته است
این روش از نظر عددی محاسبهٔ پیچیده‌تری داره و زمان کامپایل نمیشه درست حسابش کرد. روش‌های دیگه‌ای هم وجود دارن مثل روش تبدیل همگرایی افزایشی اویلر (OEIS A054387) که اثبات می‌کنه:با بررسی تمام این سری‌ها متوجه میشیم که خطای عددی افزایشی در فرمول BBP از تمام فرمول‌های پیوسته و سری‌های گسستهٔ دیگه کمتره.ثابت‌های دیگرعدد پی تنها عدد گنگ مورد استفاده در ریاضیات نیست. با این حال در زمینهٔ محاسبات علمی به اعداد دیگه مثل عدد e (پایهٔ لگاریتم طبیعی، عدد اویلر) خیلی کم نیاز پیدا می‌کنیم. (در این مورد خاص دو دلیل داره. یکی این که به‌راحتی قابل تبدیل به محاسبات مختلط هست و دوم این که تابع استاندارد exp در زبان برنامه‌نویسی سی وجود داره (:</description>
                <category>سروش ربیعی</category>
                <author>سروش ربیعی</author>
                <pubDate>Fri, 28 Jun 2019 23:24:42 +0430</pubDate>
            </item>
            </channel>
</rss>