decimal یکی از ماژولهای 1 به حساب میآید و شامل مجموعهای از توابع میشود که یکی از آنها 1 Decimal در پایتون است. ماژول decimal در پایتون از گرد کردن درست محاسبات ریاضی ممیز شناور پشتیبانی میکند. در این نوشتار 1 تابع Decimal در پایتون و ماژول decimal در پایتون ارائه شده است.
ماژول decimal در پایتون دارای توابع مختلفی برای کنترل نوع داده عددی و اجرای محاسبات ریاضی مختلف روی آن است. با استفاده از ماژول decimlal در پایتون میتوان اعداد دسیمال (مبنای ۱۰) را به طور بهینه در طول برنامه خود مدیریت کرد. ماژول decimal در پایتون توابعی را برای کنترل و چیرگی بر مشکل دقت محاسبات در مقادیر مبنای ۱۰ (دسیمال) فراهم میکند. برای استفاده از توابع مورد نیاز باید ماژول decimal را به صورت زیر Import کرد:
import decimal

بسیاری از اعداد Decimal مثل عدد 0.1 u200aنمایش دقیقی در ممیز شناور دودویی ندارند. در زمان استفاده از این اعداد در عملیات محاسبات ریاضی، نتیجهای حاصل میشود که انتظار آن وجود ندارد. برای مثال داریم:
x = 0.1
y = 0.1
z = 0.1
s = x + y + z
print(s)
خروجی قطعه کد فوق به صورت زیر است:
0.30000000000000004ملاحظه میشود که در خروجی به جای عدد 0.3 u200a، عدد 0.30000000000000004 u200aنمایش داده شده است. برای رفع این مسئله، از کلاس یا تابع Decimalu200a واقع در ماژول decimal u200aبه صورت زیر استفاده میشود:
import decimal
from decimal import Decimal
x = Decimal('0.1')
y = Decimal('0.1')
z = Decimal('0.1')
s = x + y + z
print(s)
حالا خروجی به صورت زیر خواهد بود:
0.3مشاهده میشود که با استفاده از تابع Decimal در پایتون حالا خروجی مطابق انتظار و صحیح است. ماژول decimal در پایتون از آن عملیات حسابی پشتیبانی میکند که همگان در محاسبات آموزش داده شده در مدرسه یاد گرفتهاند. برخلاف نوعهای شناور (Floats)، پایتون اعداد دسیمال (مبنای ۱۰) را به صورت دقیق نمایش میدهد و این دقت بالا وارد عملیات حسابی میشود. برای مثال عبارت زیر دقیقاً مقدار 0.0 u200aرا بازمیگرداند:
Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')
Decimal همواره با بافت و زمینهای (Context) مرتبط است که جنبههای زیر را کنترل میکند:
در حالت پیشفرض بافت یا زمینه به صورت «سراسری» (گلوبال | Global) است. به بیان دیگر بافت یا زمینه سراسری در پایتون زمینه پیشفرض در نظر گرفته میشود. همچنین میتوان یک زمینه موقت را ایجاد و تنظیم کرد که به صورت محلی بدون تحت تاثیر قرار دادن بافت سراسری موثر واقع خواهد شد. برای دریافت زمینه پیشفرض، میتوان تابع getcontext() را از ماژول decimal u200aفراخوانی کرد:
decimal.getcontext()
تابع getcontext() زمینه پیشفرض را بازمیگرداند که این زمینه میتواند سراسری (Global) یا محلی (Local) باشد. برای ایجاد بافت جدیدی که از بافت دیگری کپی شده است از تابع localcontext() u200aاستفاده میشود که سینتکس آن به صورت زیر است:
decimal.localcontext(ctx=None)
تابع localcontext() بافت جدیدی را بازمیگرداند که از بافت ctx u200aدر صورت تعیین شدن آن کپی میشود. پس از دریافت شی زمینه (Context Object)، میتوان به تنظیمات مربوط به میزان دقت و همچنین تنظیمات گرد کردن از طریق خصیصههای prec u200aو rounding u200aبه ترتیب زیر دسترسی پیدا کرد:
در پایتون ساز و کارهای گرد کردن زیر فراهم هستند:
| گرد کردن | شرح |
| ROUND_UP | گرد کردن با فاصله گرفتن از صفر |
| ROUND_DOWN | گرد کردن به سمت صفر |
| ROUND_CEILING | گرد کردن به سمت سقف (به سمت بینهایت مثبت) |
| ROUND_FLOOR | گرد کردن به سمت کف (به سمت بینهایت منفی) |
| ROUND_HALF_UP | گرد کردن به نزدیکترین، از صفر فاصله میگیرد. |
| ROUND_HALF_DOWN | گرد کردن به نزدیکترین، به سمت صفر |
| ROUND_HALF_EVEN | گرد کردن به نزدیکترین، به سمت زوج میل میکند (کمترین رقم قابل توجه) |
در ادامه مثالی آمده است که نشان میدهد چطور میتوان دقت پیشفرض و گرد کردن زمینه پیشفرض را بدست آورد:
import decimal
ctx = decimal.getcontext()
print(ctx.prec)
print(ctx.rounding)
خروجی کدهای فوق به صورت زیر است:
28 ROUND_HALF_EVEN
حال مثال دیگری در ادامه آمده است که نشان میدهد ساز و کار گرد کردن با خصوصیت 'ROUND_HALF_EVEN' u200aچگونه انجام میشود:
import decimal
from decimal import Decimal
x = Decimal('2.25')
y = Decimal('3.35')
print(round(x, 1))
print(round(y, 1))
خروجی به صورت زیر است:
2.2 3.4
اگر شیوه گرد کردن به 'ROUND_HALF_UP' u200aتغییر داده شود، نتیجه متفاوتی حاصل خواهد شد:
import decimal
from decimal import Decimal
ctx = decimal.getcontext()
ctx.rounding = decimal.ROUND_HALF_UP
x = Decimal('2.25')
y = Decimal('3.35')
print(round(x, 1))
print(round(y, 1))
خروجی کدهای فوق به صورت زیر خواهد بود:
2.3 3.4در مثالی که در ادامه آمده، نشان داده شده است که چگونه زمینه پیشفرض باید کپی شود و ساز و کار گرد کردن به حالت 'ROUND_HALF_UP' u200aتغییر کند:
import decimal
from decimal import Decimal
x = Decimal('2.25')
y = Decimal('3.35')
with decimal.localcontext() as ctx:
print('Local context:')
ctx.rounding = decimal.ROUND_HALF_UP
print(round(x, 1))
print(round(y, 1))
print('Global context:')
print(round(x, 1))
print(round(y, 1))
خروجی کدهای فوق در ادامه آمده است:
Local context: 2.3 3.4 Global context: 2.2 3.4ملاحظه میشود که زمینه محلی تاثیری روی زمینه سراسری نمیگذارد. بعد از بلوک with u200a، پایتون از ساز و کار گرد کردن پیشفرض استفاده میکند.

تقریباً همه دورههای ویدیویی مرتبط با آموزش پایتون در قالب یک مجموعه آموزشی در پلتفرم فرادرس جمعآوری شدهاند. در مجموعه آموزشهای پایتون علاوه بر دورههای مقدماتی، تکمیلی و پیشرفته، دورههای پروژه محور آموزش پایتون و سایر دورههای مربوط به کاربرد پایتون در حوزههای مختلف برنامه نویسی نیز در دسترساند. جدیدترین دوره آموزشی این مجموعه دوره آموزش پیشرفته ترفندهای پایتون است که در آن ترفندهای استفاده از تابع Decimal در پایتون هم شرح داده شدهاند. در تصویر فوق تنها برخی از دورههای آموزشی پروژهمحور مجموعه آموزش پایتون قابل مشاهده هستند.
سازنده دسیمال (Decimal Constructor) امکان ایجاد شی Decimal جدیدی را بر پایه یک مقدار فراهم میکند:
Decimal(value='0', context=None)
آرگومان value u200aمیتواند از نوع «صحیح» (Integer)، «رشتهای» (String)، «تاپل» (Tuple)، «ممیز شناور» (Float) یا شیء Decimal دیگری باشد. در صورتی که مقداری برای آگومان مربوطه تعیین نشود، مقدار پیشفرض یعنی 0 استفاده خواهد شد.
در صورتی که مقدار آرگومان value u200aاز جنس تاپل باشد، باید شامل ۳ جزء شود:
(sign, (digit1,digit2, digit3,...), exponent)
برای مثال میتوان عدد پی را به صورت زیر نوشت:
3.14 = 314 x 10^-2در مثال فوق تاپل مربوطه همانطور که در ادامه آمده، دارای ۳ عنصر مختلف است:
بنابراین لازم است تاپل زیر به سازنده Decimal u200aارجاع داده شود:
import decimal
from decimal import Decimal
x = Decimal((0, (3, 1, 4), -2))
print(x)
خروجی کدهای فوق به صورت زیر است:
3.14ملاحظه میشود که دقت بافت دسیمال تنها عملیات ریاضی را تحت تاثیر قرار میدهد و در سازنده Decimal u200aموثر نیست. در ادامه مثال دیگری ارائه شده است:
import decimal
from decimal import Decimal
decimal.getcontext().prec = 2
pi = Decimal('3.14159')
radius = 1
print(pi)
area = pi * radius * radius
print(area)
وقتی از یک عدد ممیز شناور استفاده میشود که دارای بازنمایی یا نمایش شناور دودویی دقیقی نیست، سازنده Decimal نمیتواند بازنمایی دسیمال دقیقی را ایجاد کند. برای مثال داریم:
import decimal
from decimal import Decimal
x = Decimal(0.1)
print(x)
خروجی:
0.1000000000000000055511151231257827021181583404541015625در عمل برای ساخت یک Decimal u200aدر پایتون از رشته یا تاپل استفاده میشود.
کلاس Decimal u200aتعدادی عملیات ریاضی مثل sqrt u200aو log u200aرا فراهم میکند. اگرچه، دارای تمام توابع تعریف شده در ماژول math u200aنیست.
وقتی توابع ماژول math u200aبرای اعداد دسیمال مورد استفاده قرار میگیرند، پایتون قبل از انجام عملیات حسابی اشیای Decimal u200aرا به ممیز شناور تبدیل میکند. این باعث میشود که دقت ساخته شده در اشیای دسیمال از دست برود.
پس از آشنایی مقدماتی با تابع Decimal در پایتون و درک نیاز به ماژول decimal، بهتر است در ادامه به توابع مهم ارائه شده در این ماژول پرداخته شود.

برای تقویت و بهبود حاصل جواب، عملیات حسابی مختلف را میتوان با استفاده از تابع Decimal در پایتون یا به بیان صحیحتر، ماژول decimal پایتون روی دادههای مبنای ۱۰ (دسیمال | دهدهی) یا دادههای عددی اجرا کرد. میتوان اعداد «ممیز دسیمال» (ممیز دهدهی| Decimal Point | دهدهی اعشاری) را با استفاده از تابع Decimal در پایتون یعنی decimal.Decimal() همانگونه تعریف کرد که پیشتر هم نشان داده شد. نحوه استفاده از این تابع به صورت زیر انجام میشود:
import decimal
variable = decimal.Decimal(decimal-number)
علاوه بر این، میتوان مقدار دقت در نتیجه محاسبات اعداد دهدهی را نیز با استفاده از تابع داخلی موجود در ماژول decimal یعنی decimal.getcontext().prec u200aکنترل کرد. سینتکس آن به صورت زیر است:
decimal.getcontext().prec = precision value
حال در ادامه توابعی معرفی و شرح داده شدهاند که به اجرای عملیات ریاضی دهدهی (دسیمال) به گونهای بهینه و با سرعت بالا کمک میکنند.
تابع exp() u200aمقدار توان را محاسبه میکند. یعنی این تابع عملیات e^x را برای عدد ورودی مشخصی از نوع اعشاری (ممیز دسیمال) محاسبه میکند. سینتکس تابع exp() u200aدر ماژول decimal در پایتون به صورت زیر است:
decimal.Decimal(decimal-number).exp()
برای درک بهتر نحوه استفاده از تابع exp() u200aدر ماژول decimal پایتون مثالی در ادامه آمده است:
import decimal as d
d.getcontext().prec = 5
#Intializing with an addition operation
val = d.Decimal(12.201) + d.Decimal(12.20)
#Calculating exponential of the decimal value
exp = val.exp()
#variable with no calculations
no_math = d.Decimal(1.131231)
print("Sum: ",val)
print("Exponential: ", exp)
print(no_math)
خروجی به صورت زیر است:
Decimal Number: 24.401 3.9557E+10 1.131231000000000097571728474576957523822784423828125ملاحظه میشود که تعداد کل رقمها در خروجی برابر با ۵ رقم است. دلیلش این است که میزان دقت در اینجا برابر با ۵ تنظیم شده است.
چیزی که باید به خاطر داشت این است که مقدار دقت محاسبات، زمانی اِعمال میشود که عملیات ریاضی روی ۲ عدد از نوع دسیمال اجرا شوند. وقتی که متغیری به طور مستقیم ایجاد میشود (مثل متغیر no_math در کدهای بالا)، میزان دقت تعیین شده موثر نخواهد بود.
تابع sqrt() در ماژول decimal پایتون برای محاسبه مقدار ریشه دوم عدد دسیمال ارجاع شده استفاده میشود. سینتکس و نحوه استفاده از این تابع به صورت زیر است:
decimal.Decimal(decimal-number).sqrt()
در این بخش مثالی برای آموزش نحوه استفاده از تابع sqrt() در ماژول decimal پایتون ارائه شده است:
import decimal as d
d.getcontext().prec = 3
val = d.Decimal(122.20)
sqrt = val.sqrt()
print("Decimal Number: ",val)
print("Square root of the decimal number: ",sqrt)
خروجی مثال فوق به صورت زیر است:
Decimal Number: 122.2000000000000028421709430404007434844970703125 Square root of the decimal number: 11.1باز هم لازم است توجه شودکه چگونه مقدار اعلان شده حاوی عدد دسیمال کامل است، در حالی که مقدار محاسبه شده از میزان دقت تعیین شده یعنی دقت ۳ رقمی تبعیت میکند.
برای مشاهده عملیات ریاضی بیشتر، پیشنهاد میشود مقاله آشنایی با ماژول Math در پایتون را مطالعه کنید.
در ماژول دسیمال پایتون توابع زیر برای محاسبه مقادیر لگاریتمی اعداد دهدهی فراهم شدهاند:
تابع decimal.ln() u200au200aمقدار لگاریتم طبیعی عدد دهدهی را مطابق زیر بازمیگرداند:
decimal.Decimal(decimal-number).ln()
تابع decimal.log10() u200aبرای محاسبه مقدار log با مبنای ۱۰ از عدد دسیمالی استفاده میشود که به آن ارجاع شده است. سینتکس آن در ادامه آمده است:
decimal.Decimal(decimal-number).log10()
مثال مربوطه در ادامه آمده است:
import decimal as d
d.getcontext().prec = 2
val = d.Decimal(122.20)
log = val.ln()
print("Natural log value of the decimal number: ",log)
log_10 = val.log10()
print("Log value with base 10 of the decimal number: ",log_10)
خروجی:
Natural log value of the decimal number: 4.8 Log value with base 10 of the decimal number: 2.1
تابع decimal.compare() u200aدو عدد دهدهی یا همان دسیمال را مقایسه میکند و مقادیر را بسته به شرایط به صورت زیر خروجی میدهد:
مثال مربوطه در ادامه آمده است:
import decimal as d
valx = d.Decimal(122.20)
valy = d.Decimal(123.01)
print("Value 1: ",valx)
print("Value 2: ",valy)
compare = valx.compare(valy)
print(compare)
خروجی:
Value 1: 122.2000000000000028421709430404007434844970703125 Value 2: 123.0100000000000051159076974727213382720947265625 -1
تابع decimal.copy_abs() مقادیر قدر مطلق عدد دهدهی علامتداری که به آن ارجاع شده است را بازمیگرداند. سینتکس این تابع در ماژول decimal پایتون به صورت زیر است:
decimal.Decimal(signed decimal number).copy_abs()
مثال مربوط به این تابع به صورت زیر است:
import decimal as d
valx = d.Decimal(-122.20)
print("Value 1: ",valx)
absolute = valx.copy_abs()
print("Absolute value of the given decimal number: ",absolute)
خروجی مثال فوق در ادامه آمده است:
Value 1: -122.2000000000000028421709430404007434844970703125 Absolute value of the given decimal number: 122.2000000000000028421709430404007434844970703125
ماژول decimal پایتون حاوی توابع زیر برای محاسبه مقادیر کمینه و بیشینه اعداد دهدهی یا همان دسیمال در پایتون است:
سینتکس هر یک از این دو تابع در ادامه آمده است:
#Syntax for min() function-
decimal1.min(decimal2)
#Syntax for max() function-
decimal1.max(decimal2)
این مثال در ادامه ملاحظه میشود:
import decimal as d
valx = d.Decimal(122.20)
valy = d.Decimal(123.01)
print("Value 1: ",valx)
print("Value 2: ",valy)
min_val = valx.min(valy)
print("The minimum of the two values: ",min_val)
max_val = valx.max(valy)
print("The maximum of the two values: ",max_val)
خروجی:
Value 1: 122.2000000000000028421709430404007434844970703125 Value 2: 123.0100000000000051159076974727213382720947265625 The minimum of the two values: 122.2000000000000028421709430 The maximum of the two values: 123.0100000000000051159076975
ماژول decimal در پایتون حاوی مجموعهای از توابع داخلی برای اجرای عملیات منطقی روی اعداد دسیمال (دهدهی) است که از جمله آنها میتوان به XOR ،OR ،AND و سایر موارد اشاره کرد.
سینتکس هر یک از توابع فوق در ادامه آمده است:
#Syntax for logical_and() function-
decimal1.logical_and(decimal2)
#Syntax for logical_or() function-
decimal1.logical_or(decimal2)
#Syntax for logical_xor() function-
decimal1.logical_xor(decimal2)
این مثال در ادامه ملاحظه میشود:
import decimal as d
valx = d.Decimal(1001)
valy = d.Decimal(1111)
print("Value 1: ",valx)
print("Value 2: ",valy)
AND = valx.logical_and(valy)
print("The logical AND value of the two decimals: ",AND)
OR = valx.logical_or(valy)
print("The logical OR value of the two decimals: ",OR)
XOR = valx.logical_xor(valy)
print("The logical XOR value of the two decimals: ",XOR)
خروجی مثال فوق در ادامه آمده است:
Value 1: 1001 Value 2: 1111 The logical AND value of the two decimals: 1001 The logical OR value of the two decimals: 1111 The logical XOR value of the two decimals: 110
در ادامه فهرستی برای جمعبندی مواردی ارائه شده است که در این نوشتار شرح داده شدند:
اگر این مطلب برای شما مفید بوده است، آموزشها و مطالب زیر نیز به شما پیشنهاد میشوند:
برچسب:
نویسنده: خنجی