print('Natija:', x*2)
Oʻnli sonlarning ikkiliq sanoq sistemasidagi koʻrinishi cheksiz raqamlardan iborat boʻlishi mumkinligi bunday sonlarni yahlitlashga va buning oqibatida aniqlikning yoʻqolishiga olib keladi. Buning oldini olish uchun sonlarni Decimal() da satr shaklida yozish tavsiya qilinadi:
Decimal('1.23456').
Zarur hollarda str() funktsiyasidan foydalanish mumkin. Masalan,
Decimal(str(3**0.5 / 2))
ifodaning natijasi '0.8660254037844386' tarzida boʻladi.
Sonlarni Decimal tipiga kortej shaklida ham uzatish mumkin. Bu kortej umumiy koʻrinishda quyidagicha yozilishi mumkin:
(ishora, (raqam, ..., digit), mantissa),
Bu yerda ishora musbat son uchun ‑0, manfiy sonlar uchun ‑ 1. Masalan:
>>> Decimal((0, (1, 2, 3, 4, 5, 6), -5))
Decimal('1.23456')
Sonlarni yahlitlashda kerakli raqamlar sonini quantize() metodi yordamida koʻrsatish mumkin:
Decimal('1.51567').quantize(Decimal('1.11'), rounding = ROUND_DOWN)
Decimal('1.51567').quantize(Decimal('1.11'), rounding = ROUND_UP)
Kontekstlar – bu arifmetik amallarni bajarish muhiti demakdir. Ular ammallarni qanday aniqlikda hisoblash va yahlitlash hamda qanday signallarni istisnoli vaziyat deb hisoblash, qaysilarini inkor qilish qoidalarini belgilab beradi. Kontekstning maydonlari quyidagi ma’nolarni anglatadi:
prec — arifmetik amallar aniqligini belgilaydi va u [0, MAX_PREC] oqaliqda boʻlishi mumkin;
rounding — yahlitlash rejimini oʻrnatadi;
traps va flags maydonlari oʻz ichiga signallar roʻyhati hamda ularni nazorat qilish alomatlarini oladi;
Emin va Emax maydonlari daraja koʻrsatkichlarini belgilab beradi. Emin ning qiymatlari [MIN_EMIN, 0], Emax ning qiymatlari esa [0, MAX_EMAX] diapazonda yotadi;
Capitals maydoni daraja belgisini ekranga qanday shaklda chiqarish kerakligini koʻrsatadi. Toʻgʻridan-toʻgʻri bu qiymat 1 ga teng va u “E”, 0 esa “e” harfiga mos keladi;
Clamp maydoni 1 yoki 0 ga teng boʻladi. Agar 1 boʻlsa, oʻnli sonning e eksponentasi [Emin - prec + 1, Emax - prec + 1] diapazonda boʻladi. Agar clamp=0 boʻsa, daraja koʻrsatkichi Emax dan katta boʻla olmaydi.
Har bir jarayon oʻz kontekstiga ega boʻlib, zarur hollarda uni getcontext() yoki setcontext() metodlari bilan oʻzgartirish mumkin. Buning uchun kontekstning maydonlarini ehtiyojga koʻra qayta belgilanadi. Masalan,
my_context = Context(prec = 9, Emax = 99999).
Agar qaysidir maydon koʻrsatilmagan boʻlsa, bu qiymatlar kontekstning DefaultContext qiymatlaridan olinadi. Bayroqchalar koʻrsatilmagan yoki tushirib qoldirilgan boʻlsa, bu holat bayroqchalarning tozalanishiga olib keladi:
my_context = Context(prec = 3, rounding = ROUND_DOWN)
setcontext(my_context)
print(1/8, Decimal(1)/Decimal(8))
print(1/15, Decimal(1)/Decimal(15))
print(180/13, Decimal(180)/Decimal(13))
Shuningdek, Decimal moduli ikkita tayyor kontkestni taklif etadi: BasicContext va ExtendedContext:
from decimal import *
print(BasicContext)
print(ExtendedContext)
Agar BasicContext ga e`tibor qaratilsa, unda dasturlarni otladka qilishda foydali boʻlgan koʻplab istisnoli vaziyatlar nazarda tutilganini koʻrish mumkin. Masalan, BasicContext da
Decimal(1)/Decimal(0)
buyrugʻi hatolikka ishora qiladi, ExtendedContext da esa hech qanday istisnoli vaziyatni qayd etilmaydi.
Hatoliklarni kuzatib borish uchun bayroqchalar asosida ishlovchi mahsus signallar mavjud. Bu bayroqchalar tushirib qoʻyilmaguncha faol hisoblanadi. Yuqoridagi ExtendedContext ning flags=[] hususiyatiga e`tibor bering. Bu holat uchun :
Decimal(1)/Decimal(3)
amali '0.333333333' natijani beradi. Ana shu bayroqchalarning flags=[Inexact, Rounded], traps=[] holati uchun)
Decimal(1)/Decimal(0)
buyrugʻi “Infinity” natijani qaytaradi.
from decimal import *
setcontext(ExtendedContext)
print(getcontext())
print(Decimal(1)/Decimal(3))
print(getcontext())
print(Decimal(1)/Decimal(0))
Bayroqchalarni tushirib qoʻyish uchun clear_flags() metodidan foydalanish mumkin:
getcontext().clear_flags().
Istisnoli vaziyatlarni tutib qolish uchun traps parametri qiymatlarini oʻzgartirishga toʻgʻri keladi:
from decimal import *
getcontext().traps[Rounded] = 1
print(Decimal(1)/Decimal(16))
print(Decimal(1)/Decimal(17))
Yuqoridagi kodda Rounded faollashtirilganidan keyin, Decimal(1)/Decimal(16) buyrugʻi hatosiz bajarildi, chunki natija prec da koʻrsatilgan diapazonga tushadi va yahlitlashga ehtiyoj yoʻq. Decimal(1)/Decimal(17) amalining natijasini esa yahlitlashga toʻgʻri keladi va bu holat istisnoli vaziyatni yuzaga keltiradi.
Agar FloatOperation signali 1 ga oʻzgartirilgan boʻlsa, haqiqiy sonlarni Decimal tipiga oʻtkazish hatolikni yuzaga keltirishi mumkin:
>>> getcontext().traps[FloatOperation] = 1
>>> Decimal(0.1)
Traceback (most recent call last):
File "", line 1, in
decimal.FloatOperation: []
Context metodining argumenti satr raqamlar ketma⁃ketligilan iborat boʻlmagan hollarni qayta ishlashga imkon beradi. Toʻgʻridan‑toʻgʻri bu parametrning qiymati ‑ None boʻlib, bunday satrlarni NaN ga aylantiradi:
>>> Decimal('dssd')
Decimal('NaN')
Shunday qilib, istisnoli vaziyatlarni tutib qolish orqali koʻplab kutilmagan signallarni tutib qolish evaziga ishonchli dasturlar ishlab chiqish mumkin boʻladi.
Decimal tipidagi sonlar ustida int va float tipidagi sonlar uchun ruhsat berilgan barcha amallarni bajarish mumkin. Faqat Decimal tipida '%' (qoldiq) operatorini bajarganda natija va boʻlinuvchining ishorasi bir hil boʻladi:
from decimal import *
print('Natural sonlar uchun :', -10%4, 10 % -4)
print('Decimal sonlar uchun ', Decimal(-10) % Decimal(4))
print('Decimal sonlar uchun ', Decimal(10) % Decimal(-4))
Bitta matematik ifodada Decimal, float hamda fractions.Fraction kasrlar tipidagi ma’lumotlarning uchrashi mumkin emas. Agar FloatOperation bayroqchasi oʻrnatilmagan boʻlsa, faqat taqqoslash amalidagina bunday tipdagi sonlardan birgalikda foydalanish mumkin:
from decimal import *
print(Decimal('1.2') == 1.2)
from fractions import Fraction
print(Decimal('1.2') == Fraction(6, 5))
Do'stlaringiz bilan baham: |