رفتن به محتوای اصلی
بازگشت به وبلاگ

داده و اتصال فنی

سرریز عدد صحیح در NumPy؛ قبل از ضرب نوع را عوض کنیم یا بعد؟

سرریز عدد صحیح را با مربعِ±۳۰۰۰۰ و مرزِ۱۸۱/۱۸۲ بسنجید؛ تبدیلِبعدی نتیجه را تعمیر نمی‌کند و int64 نیز بودجهٔحاصل می‌خواهد.

سرریزِ عددِ صحیحِ آرایه می‌تواند پیش از تبدیل به نوعِ بزرگ‌تر رخ دهد. اگر حاصلِ خراب را بعداً int64 کنیم، رقمِ اصلی خودکار برنمی‌گردد. این تمرین مربعِ دو عددِ int16 را در دو مسیرِ «اول ضرب، بعد تبدیل» و «اول تبدیل، بعد ضرب» می‌سنجد و با intِ پایتون مقایسه می‌کند؛ بحثِ گردکردنِ جمعِ float نیست.

ورودی جا می‌شود، حاصل شاید نه

دو مقدارِ ۳۰۰۰۰ و−۳۰۰۰۰ در int16ِ علامت‌دار جا می‌شوند؛ دامنهٔ این نوع از−۳۲۷۶۸تا۳۲۷۶۷ است. اما مربعِ هر دو۹۰۰۰۰۰۰۰۰ می‌شود و در آن دامنه جا ندارد. مناسب‌بودنِ نوع برایِ ورودی، به معنیِ مناسب‌بودنِ آن برایِ تمامِ مقدارهایِ میانی و خروجی نیست.

در اجرایِ NumPy۲٫۳٫۵، ضربِ آرایهٔint16 در خودش برایِ هر دو مقدار−۵۸۸۸ برمی‌گرداند. این عدد علامتِ واقعیِ مربعِ منفی نیست؛ نتیجهٔ محاسبه در دامنهٔ محدودِ همان نوع است. در کد، اصلِ آرایه، dtype و خروجیِ هر مرحله ثبت می‌شوند تا محلِ خطا پنهان نشود.

تبدیلِ بعدی اطلاعات را بازسازی نمی‌کند

مسیرِ اول، همان حاصلِ int16 را به int64 تبدیل می‌کند. دو مقدار همچنان−۵۸۸۸ می‌مانند. نوعِ بزرگ‌تر توانِ نمایشِ عددهایِ بیشتری دارد، اما نمی‌داند پیش از سرریز کدام عدد قرار بوده ساخته شود. این همان دلیلِ مهمِ جداکردنِ ورودیِ سالم از نتیجهٔ ازپیش‌آسیب‌دیده است.

در مسیرِ دوم، ابتدا خودِ دو ورودی را int64 و سپس مربع می‌کنیم. خروجیِ واقعی[۹۰۰۰۰۰۰۰۰،۹۰۰۰۰۰۰۰۰] است. oracleِ مستقل هر عنصر را پیش از ضرب به intِ پایتون می‌برد و همان دو مربع را می‌دهد؛ از حاصلِ سرریز‌شده برایِ ساختِ مرجع استفاده نکرده‌ایم.

ترتیبِ عملیاتنوعِ ضربمربعِ ۳۰۰۰۰
ضرب،سپس تبدیلint16−۵۸۸۸ باقی می‌ماند
تبدیلِ ورودی،سپس ضربint64۹۰۰۰۰۰۰۰۰
مرجعِ intِ پایتونصحیحِ بااندازهٔانعطاف‌پذیر۹۰۰۰۰۰۰۰۰

حتی sum باdtypeِ int64 پس ازضربِ سرریز‌شده،مقدارهایِ خراب را جمع می‌کند: اینجا−۱۱۷۷۶به‌جایِ ۱۸۰۰۰۰۰۰۰۰. نوعِ ورودی،حاصلِ باریک،تبدیلِ بعدی،ورودیِ ارتقایافته وحاصلِ پهن درJSON جدا ثبت شده‌اند. مربعِ صفر نیز درمسیرِ اصلاح‌شده واقعاًصفر می‌شود.

یک مرزِ کوچک را هم آزمایش کنیم

فقط عددِ بسیار بزرگ انتخاب نکرده‌ایم. مربعِ ۱۸۱ و−۱۸۱ برابرِ ۳۲۷۶۱ است و در دامنهٔ int16 می‌ماند. مربعِ ۱۸۲ و−۱۸۲ برابرِ ۳۳۱۲۴ است و بیرونِ آن می‌رود؛ خروجیِ مشاهده‌شدهٔ int16 برابرِ−۳۲۴۱۲ است. جدولِ JSON هر چهار ورودی، حاصلِ محدود و مرجعِ دقیق را کنارِ هم دارد.

این مثال دربارهٔ همهٔ عملگرها یا همهٔ قواعدِ promotion در NumPy نیست. حتی تبدیلِ درستِ ورودی به int64 نیز برایِ هر عددِ ممکن کافی نیست؛ همان نوع دامنهٔ محدودِ خودش را دارد. انتخابِ نوع باید بر اساسِ دامنهٔ مقدارهایِ میانیِ همان محاسبه باشد، نه صرفاً بزرگ‌تر بودنِ نامِ آن.

برایِ مسیرِ اصلاح‌شده، بودجهٔ حاصل بگذاریم

تابعِ checked_squareِ تمرین حداکثر۱۶مقدارِ صحیحِ غیرbool می‌گیرد و قبل از ساختِ آرایه، مربعِ هر مقدار را با maxِ int64 می‌سنجد. تنها وقتی حاصل در دامنهٔ اعلام‌شده است، مسیرِ ضربِ int64 اجرا می‌شود. ورودیِ True،عددِ ۳۰۳۷۰۰۰۵۰۰ و مقدارِ ۱٫۵ در سه آزمون واقعاً رد می‌شوند.

این کنترل، قراردادِ محدودِ مربعِ صحیح است. تبدیل به float برایِ فرار از سرریز ممکن است دقتِ صحیح را عوض کند و در اینجا راه‌حلِ عمومی معرفی نشده است. همچنین نوعِ پایتون محدودیتِ حافظه و منابعِ اجرا را حذف نمی‌کند؛ مثالِ حاضر ورودیِ بزرگ یا محاسبهٔ نامحدود نمی‌سازد.

کاربردِ بعدیِ این بررسی چیست؟

در مثالِ Sobel، علامت و دامنهٔ مقدارهایِ میانی اهمیت دارند؛ این صفحه خودِ ضدنمونهٔ عددِ صحیح را با NumPy اجرا می‌کند و کیفیتِ تصویر یا صوت را نمی‌سنجد. جمعِ float و ترتیب افتِ دقتِ دیگری دارد؛ سرریزِ صحیح را با آن یکی نکنیم.

برای ادامه به مبانی هوش مصنوعی بروید. قبل از اجرایِ تبدیل رویِ دادهٔ واقعی، ورودیِ مرزی و مرجعِ مستقل بسازید و typeِ عملیات را ثبت کنید؛ این تمرین روشِ پردازشِ داخلی یا نتیجهٔ محصول اپرا را اعلام نمی‌کند.

فایل تمرین و منبع

کد مستقلِ تمرینِ محدود · تمام خروجیِ واقعیِ همین تمرین؛ JSON

منابع در 2026-11-04 خوانده شدند؛ این تاریخ، تاریخ انتشار منبع نیست. مثال‌ها و فایل‌های این راهنما آموزشی و ساختهٔ تحریریه‌اند.

برای این نیاز، کدام خدمت مناسب‌تر است؟

تماس و منشی، چت سایت و تحلیل مکالمه سه مسیر متفاوت‌اند. ابتدا خدمت متناسب نیازتان را انتخاب کنید.

انتخاب میان سه خدمتراهنمای شروع با تیم اپرا

برآورد هزینه