Python میں اعشاریہ اور عدد کو "راؤنڈ” اور "decimal.quantize” کے ساتھ گول کرنا

کاروبار

مندرجہ ذیل وضاحت کرتا ہے کہ Python میں نمبروں کو گول کرکے یا یکساں نمبر پر کیسے گول کیا جائے۔ اعداد کو فلوٹنگ پوائنٹ فلوٹ یا انٹیجر int قسم کے سمجھا جاتا ہے۔

  • بلٹ ان فنکشن (مثال کے طور پر پروگرامنگ زبان میں):round()
    • ہندسوں کی کسی بھی تعداد تک گول اعشاریہ۔
    • ہندسوں کی کسی بھی تعداد میں مکمل عدد۔
    • round() ایک یکساں نمبر پر راؤنڈ کرتا ہے، عام راؤنڈنگ پر نہیں۔
  • معیاری لائبریریdecimalquantize()
    • Decimalکسی چیز کی تخلیق
    • ہندسوں کی کسی بھی تعداد میں اعشاریہ کا گول اور یکساں نمبروں پر گول کرنا
    • ہندسوں کی کسی بھی تعداد میں عدد کا مکمل اور یکساں نمبروں کو گول کرنا
  • ایک نئے فنکشن کی وضاحت کریں۔
    • ہندسوں کی کسی بھی تعداد تک اعشاریہ کو گول کریں۔
    • ہندسوں کی کسی بھی تعداد میں مکمل عدد
    • نوٹ: منفی اقدار کے لیے

نوٹ کریں کہ، جیسا کہ اوپر بتایا گیا ہے، بلٹ ان فنکشن راؤنڈ کوئی عام راؤنڈنگ نہیں ہے، بلکہ ایک یکساں نمبر پر گول کرنا ہے۔ تفصیلات کے لیے نیچے ملاحظہ کریں۔

بلٹ ان فنکشن (مثال کے طور پر پروگرامنگ زبان میں):round()

راؤنڈ() بلٹ ان فنکشن کے طور پر فراہم کیا جاتا ہے۔ یہ کسی بھی ماڈیول کو درآمد کیے بغیر استعمال کیا جا سکتا ہے۔

پہلی دلیل اصل نمبر ہے، اور دوسری دلیل ہندسوں کی تعداد ہے (کتنے ہندسوں کو گول کرنا ہے)۔

ہندسوں کی کسی بھی تعداد تک گول اعشاریہ۔

درج ذیل فلوٹنگ پوائنٹ فلوٹ قسم کے لیے پروسیسنگ کی ایک مثال ہے۔

اگر دوسری دلیل کو چھوڑ دیا جاتا ہے، تو اسے ایک عدد میں گول کر دیا جاتا ہے۔ قسم بھی ایک عدد int قسم بن جاتی ہے۔

f = 123.456

print(round(f))
# 123

print(type(round(f)))
# <class 'int'>

اگر دوسری دلیل کی وضاحت کی گئی ہے، تو یہ فلوٹنگ پوائنٹ فلوٹ قسم لوٹاتا ہے۔

اگر ایک مثبت عدد متعین کیا جاتا ہے، تو اعشاریہ جگہ کی وضاحت کی جاتی ہے۔ اگر منفی عدد متعین کیا جاتا ہے، تو عددی جگہ کی وضاحت کی جاتی ہے۔ قریب ترین دسویں تک -1 راؤنڈ، قریب ترین سوویں تک -2 راؤنڈ، اور ایک عدد (پہلے مقام) پر 0 راؤنڈ، لیکن چھوڑے جانے کے برعکس، فلوٹ کی قسم لوٹاتا ہے۔

print(round(f, 1))
# 123.5

print(round(f, 2))
# 123.46

print(round(f, -1))
# 120.0

print(round(f, -2))
# 100.0

print(round(f, 0))
# 123.0

print(type(round(f, 0)))
# <class 'float'>

ہندسوں کی کسی بھی تعداد میں مکمل عدد۔

درج ذیل انٹیجر int قسم کے لیے پروسیسنگ کی ایک مثال ہے۔

اگر دوسری دلیل کو چھوڑ دیا جاتا ہے، یا اگر 0 یا ایک مثبت عدد متعین کیا جاتا ہے، تو اصل قدر اسی طرح لوٹائی جاتی ہے۔ اگر منفی عدد متعین کیا جاتا ہے، تو اسے متعلقہ عددی ہندسے پر گول کر دیا جاتا ہے۔ دونوں صورتوں میں، ایک عدد int قسم لوٹا دی جاتی ہے۔

i = 99518

print(round(i))
# 99518

print(round(i, 2))
# 99518

print(round(i, -1))
# 99520

print(round(i, -2))
# 99500

print(round(i, -3))
# 100000

round() ایک یکساں نمبر پر راؤنڈ کرتا ہے، عام راؤنڈنگ پر نہیں۔

نوٹ کریں کہ Python 3 میں بلٹ ان راؤنڈ() فنکشن کے ساتھ راؤنڈنگ ایک یکساں نمبر پر ہوتی ہے، عام راؤنڈنگ میں نہیں۔

جیسا کہ سرکاری دستاویزات میں لکھا گیا ہے، 0.5 کو 0، 5 کو 0 پر گول کیا جاتا ہے، وغیرہ۔

print('0.4 =>', round(0.4))
print('0.5 =>', round(0.5))
print('0.6 =>', round(0.6))
# 0.4 => 0
# 0.5 => 0
# 0.6 => 1

print('4 =>', round(4, -1))
print('5 =>', round(5, -1))
print('6 =>', round(6, -1))
# 4 => 0
# 5 => 0
# 6 => 10

یکساں نمبر پر گول کرنے کی تعریف درج ذیل ہے۔

اگر حصہ 0.5 سے کم ہے، تو اسے نیچے گول کریں؛ اگر حصہ 0.5 سے زیادہ ہے تو اسے گول کر لیں؛ اگر حصہ بالکل 0.5 ہے، تو اسے نیچے اور گول کرنے کے درمیان یکساں نمبر تک گول کریں۔
Rounding – Wikipedia

0.5 کو ہمیشہ چھوٹا نہیں کیا جاتا ہے۔

print('0.5 =>', round(0.5))
print('1.5 =>', round(1.5))
print('2.5 =>', round(2.5))
print('3.5 =>', round(3.5))
print('4.5 =>', round(4.5))
# 0.5 => 0
# 1.5 => 2
# 2.5 => 2
# 3.5 => 4
# 4.5 => 4

بعض صورتوں میں، یکساں نمبر پر گول کرنے کی تعریف دو اعشاریہ کے بعد پروسیسنگ پر بھی لاگو نہیں ہوتی ہے۔

print('0.05 =>', round(0.05, 1))
print('0.15 =>', round(0.15, 1))
print('0.25 =>', round(0.25, 1))
print('0.35 =>', round(0.35, 1))
print('0.45 =>', round(0.45, 1))
# 0.05 => 0.1
# 0.15 => 0.1
# 0.25 => 0.2
# 0.35 => 0.3
# 0.45 => 0.5

یہ اس حقیقت کی وجہ سے ہے کہ اعشاریہ کو فلوٹنگ پوائنٹ نمبرز کے طور پر بالکل نہیں دکھایا جا سکتا، جیسا کہ سرکاری دستاویزات میں بتایا گیا ہے۔

فلوٹنگ پوائنٹ نمبرز کے لیے راؤنڈ() کا برتاؤ آپ کو حیران کر سکتا ہے۔:مثال کے طور پر، راؤنڈ (2.675, 2) آپ کو 2.68 کے بجائے 2.67 دے گا جیسا کہ توقع ہے۔ یہ کوئی بگ نہیں ہے۔:یہ اس حقیقت کا نتیجہ ہے کہ زیادہ تر اعشاریوں کو فلوٹنگ پوائنٹ نمبرز کے ذریعے بالکل درست طور پر ظاہر نہیں کیا جا سکتا۔
round() — Built-in Functions — Python 3.10.2 Documentation

اگر آپ اعشاریہ کی عمومی راؤنڈنگ یا یکساں نمبروں پر درست گول کرنا چاہتے ہیں، تو آپ معیاری لائبریری اعشاریہ کوانٹائز (ذیل میں بیان کیا گیا ہے) استعمال کرسکتے ہیں یا ایک نئے فنکشن کی وضاحت کرسکتے ہیں۔

یہ بھی نوٹ کریں کہ Python 2 میں round() کسی یکساں نمبر پر نہیں بلکہ راؤنڈنگ ہے۔

معیاری لائبریری اعشاریہ کی مقدار ()

معیاری لائبریری کا اعشاریہ ماڈیول درست اعشاریہ فلوٹنگ پوائنٹ نمبرز کو ہینڈل کرنے کے لیے استعمال کیا جا سکتا ہے۔

اعشاریہ ماڈیول کا کوانٹائز () طریقہ استعمال کرتے ہوئے، راؤنڈنگ موڈ کی وضاحت کر کے نمبروں کو گول کرنا ممکن ہے۔

quantize() طریقہ کار کے آرگومینٹ راؤنڈنگ کے لیے مقرر کردہ اقدار کے بالترتیب درج ذیل معنی ہیں۔

  • ROUND_HALF_UP:جنرل راؤنڈنگ
  • ROUND_HALF_EVEN:یکساں نمبروں پر گول کرنا

اعشاریہ ماڈیول ایک معیاری لائبریری ہے، لہذا کسی اضافی تنصیب کی ضرورت نہیں ہے، لیکن درآمد ضروری ہے۔

from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_EVEN

ایک اعشاریہ آبجیکٹ بنانا

اعشاریہ () ڈیسیمل قسم کی اشیاء بنانے کے لیے استعمال کیا جا سکتا ہے۔

اگر آپ دلیل کے طور پر ایک فلوٹ قسم کی وضاحت کرتے ہیں، تو آپ دیکھ سکتے ہیں کہ اصل میں قدر کے ساتھ کیا سلوک کیا جاتا ہے۔

print(Decimal(0.05))
# 0.05000000000000000277555756156289135105907917022705078125

print(type(Decimal(0.05)))
# <class 'decimal.Decimal'>

جیسا کہ مثال میں دکھایا گیا ہے، 0.05 کو بالکل 0.05 نہیں سمجھا جاتا ہے۔ یہی وجہ ہے کہ اوپر بیان کردہ بلٹ ان فنکشن راؤنڈ() مثال میں 0.05 سمیت اعشاریہ کی قدروں کے لیے توقع سے مختلف قدر میں گول ہو گیا ہے۔

چونکہ 0.5 نصف (2 کی -1 طاقت) ہے، اس لیے اسے بائنری اشارے میں بالکل ظاہر کیا جا سکتا ہے۔

print(Decimal(0.5))
# 0.5

اگر آپ فلوٹ قسم کے بجائے سٹرنگ کی قسم str بتاتے ہیں، تو اسے عین قدر کی اعشاریہ قسم کے طور پر سمجھا جائے گا۔

print(Decimal('0.05'))
# 0.05

ہندسوں کی کسی بھی تعداد میں اعشاریہ کا گول اور یکساں نمبروں پر گول کرنا

قدر کو راؤنڈ آف کرنے کے لیے ڈیسیمل قسم کے آبجیکٹ سے quantize() کو کال کریں۔

quantize() کی پہلی دلیل ایک سٹرنگ ہے جس میں ہندسوں کی اتنی ہی تعداد ہے جو ہندسوں کی تعداد ہے جسے آپ تلاش کرنا چاہتے ہیں، جیسے ‘0.1’ یا ‘0.01’۔

اس کے علاوہ، ROUNDING دلیل راؤنڈنگ موڈ کی وضاحت کرتی ہے۔ اگر ROUND_HALF_UP متعین کیا گیا ہے، تو عام راؤنڈنگ استعمال کی جاتی ہے۔

f = 123.456

print(Decimal(str(f)).quantize(Decimal('0'), rounding=ROUND_HALF_UP))
# 123

print(Decimal(str(f)).quantize(Decimal('0.1'), rounding=ROUND_HALF_UP))
# 123.5

print(Decimal(str(f)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
# 123.46

بلٹ ان فنکشن راؤنڈ () کے برعکس، 0.5 کو 1 پر گول کیا جاتا ہے۔

print('0.4 =>', Decimal(str(0.4)).quantize(Decimal('0'), rounding=ROUND_HALF_UP))
print('0.5 =>', Decimal(str(0.5)).quantize(Decimal('0'), rounding=ROUND_HALF_UP))
print('0.6 =>', Decimal(str(0.6)).quantize(Decimal('0'), rounding=ROUND_HALF_UP))
# 0.4 => 0
# 0.5 => 1
# 0.6 => 1

اگر آرگیومینٹ راؤنڈنگ ROUND_HALF_EVEN پر سیٹ کی گئی ہے تو، بلٹ ان فنکشن راؤنڈ() کی طرح یکساں نمبروں پر گول کیا جاتا ہے۔

جیسا کہ اوپر ذکر کیا گیا ہے، اگر فلوٹنگ پوائنٹ فلوٹ کی قسم کو ڈیسیمل() کی دلیل کے طور پر بیان کیا گیا ہے، تو اسے اعشاریہ آبجیکٹ کے طور پر سمجھا جاتا ہے جس کی قدر فلوٹ قسم کی اصل قدر کے برابر ہوتی ہے، لہذا quantize() استعمال کرنے کا نتیجہ طریقہ توقع سے مختلف ہوگا، بالکل بلٹ ان فنکشن راؤنڈ() کی طرح۔

print('0.05 =>', round(0.05, 1))
print('0.15 =>', round(0.15, 1))
print('0.25 =>', round(0.25, 1))
print('0.35 =>', round(0.35, 1))
print('0.45 =>', round(0.45, 1))
# 0.05 => 0.1
# 0.15 => 0.1
# 0.25 => 0.2
# 0.35 => 0.3
# 0.45 => 0.5

print('0.05 =>', Decimal(0.05).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.15 =>', Decimal(0.15).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.25 =>', Decimal(0.25).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.35 =>', Decimal(0.35).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.45 =>', Decimal(0.45).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
# 0.05 => 0.1
# 0.15 => 0.1
# 0.25 => 0.2
# 0.35 => 0.3
# 0.45 => 0.5

اگر Decimal() کی دلیل کو str قسم کی سٹرنگ کے طور پر بیان کیا گیا ہے، تو اسے بالکل اسی قدر کی اعشاریہ آبجیکٹ کے طور پر سمجھا جاتا ہے، لہذا نتیجہ توقع کے مطابق ہے۔

print('0.05 =>', Decimal(str(0.05)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.15 =>', Decimal(str(0.15)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.25 =>', Decimal(str(0.25)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.35 =>', Decimal(str(0.35)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.45 =>', Decimal(str(0.45)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
# 0.05 => 0.0
# 0.15 => 0.2
# 0.25 => 0.2
# 0.35 => 0.4
# 0.45 => 0.4

چونکہ 0.5 کو فلوٹ ٹائپ کے ذریعے درست طریقے سے ہینڈل کیا جا سکتا ہے، اس لیے اعشاریہ () کی دلیل کے طور پر فلوٹ کی قسم کی وضاحت کرنے میں کوئی حرج نہیں ہے، لیکن اعشاریہ کی جگہ پر راؤنڈ کرتے وقت سٹرنگ کی قسم کی وضاحت کرنا زیادہ محفوظ ہے۔

مثال کے طور پر، 2.675 دراصل 2.67499 ہے…. فلوٹ قسم میں۔ لہذا، اگر آپ دو اعشاریہ کی جگہوں پر گول کرنا چاہتے ہیں، تو آپ کو اعشاریہ () پر ایک سٹرنگ بتانا ضروری ہے، ورنہ نتیجہ متوقع نتیجہ سے مختلف ہوگا چاہے آپ قریب ترین مکمل نمبر (ROUND_HALF_UP) یا ایک یکساں نمبر (ROUND_HALF_EVEN) پر گول کریں۔ )۔

print(Decimal(2.675))
# 2.67499999999999982236431605997495353221893310546875

print(Decimal(2.675).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
# 2.67

print(Decimal(str(2.675)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
# 2.68

print(Decimal(2.675).quantize(Decimal('0.01'), rounding=ROUND_HALF_EVEN))
# 2.67

print(Decimal(str(2.675)).quantize(Decimal('0.01'), rounding=ROUND_HALF_EVEN))
# 2.68

نوٹ کریں کہ quantize() طریقہ اعشاریہ قسم کا نمبر لوٹاتا ہے، لہذا اگر آپ فلوٹ ٹائپ نمبر پر کام کرنا چاہتے ہیں، تو آپ کو float() کا استعمال کرتے ہوئے اسے فلوٹ ٹائپ میں تبدیل کرنا ہوگا، ورنہ ایک خرابی واقع ہوگی۔

d = Decimal('123.456').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)

print(d)
# 123.46

print(type(d))
# <class 'decimal.Decimal'>

# print(1.2 + d)
# TypeError: unsupported operand type(s) for +: 'float' and 'decimal.Decimal'

print(1.2 + float(d))
# 124.66

ہندسوں کی کسی بھی تعداد میں عدد کا مکمل اور یکساں نمبروں کو گول کرنا

اگر آپ عددی ہندسے کو گول کرنا چاہتے ہیں تو پہلی دلیل کے طور پر ’10’ جیسا کچھ بتانے سے آپ کو مطلوبہ نتیجہ نہیں ملے گا۔

i = 99518

print(Decimal(i).quantize(Decimal('10'), rounding=ROUND_HALF_UP))
# 99518

اس کی وجہ یہ ہے کہ quantize() اعشاریہ آبجیکٹ کے ایکسپوننٹ کے مطابق راؤنڈنگ کرتا ہے، لیکن اعشاریہ (’10’) کا ایکسپوننٹ 0 ہے، 1 نہیں۔

آپ E کو بطور ایکسپوننٹ سٹرنگ (جیسے ‘1E1’) استعمال کر کے صوابدیدی ایکسپوننٹ کی وضاحت کر سکتے ہیں۔ exponent exponent کو as_tuple طریقہ میں چیک کیا جا سکتا ہے۔

print(Decimal('10').as_tuple())
# DecimalTuple(sign=0, digits=(1, 0), exponent=0)

print(Decimal('1E1').as_tuple())
# DecimalTuple(sign=0, digits=(1,), exponent=1)

جیسا کہ یہ ہے، نتیجہ E کا استعمال کرتے ہوئے ایکسپونینشل نوٹیشن میں ہوگا۔ اگر آپ نارمل نوٹیشن استعمال کرنا چاہتے ہیں، یا اگر آپ راؤنڈنگ کے بعد انٹیجر انٹ ٹائپ کے ساتھ کام کرنا چاہتے ہیں تو نتیجہ کو تبدیل کرنے کے لیے int() کا استعمال کریں۔

print(Decimal(i).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP))
# 9.952E+4

print(int(Decimal(i).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP)))
# 99520

print(int(Decimal(i).quantize(Decimal('1E2'), rounding=ROUND_HALF_UP)))
# 99500

print(int(Decimal(i).quantize(Decimal('1E3'), rounding=ROUND_HALF_UP)))
# 100000

اگر آرگیومینٹ راؤنڈنگ ROUND_HALF_UP پر سیٹ ہے، تو عام راؤنڈنگ ہو گی، جیسے، 5 کو 10 پر گول کر دیا جائے گا۔

print('4 =>', int(Decimal(4).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP)))
print('5 =>', int(Decimal(5).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP)))
print('6 =>', int(Decimal(6).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP)))
# 4 => 0
# 5 => 10
# 6 => 10

بلاشبہ، اگر آپ اسے سٹرنگ کے طور پر بیان کرتے ہیں تو کوئی حرج نہیں ہے۔

ایک نئے فنکشن کی وضاحت کریں۔

اعشاریہ ماڈیول کو استعمال کرنے کا طریقہ درست اور محفوظ ہے، لیکن اگر آپ ٹائپ کنورژن کے ساتھ آرام دہ نہیں ہیں، تو آپ عام راؤنڈنگ حاصل کرنے کے لیے ایک نئے فنکشن کی وضاحت کر سکتے ہیں۔

ایسا کرنے کے بہت سے ممکنہ طریقے ہیں، مثال کے طور پر، درج ذیل فنکشن۔

def my_round(val, digit=0):
    p = 10 ** digit
    return (val * p * 2 + 1) // 2 / p

اگر آپ کو ہندسوں کی تعداد بتانے اور ہمیشہ پہلے اعشاریہ پر گول کرنے کی ضرورت نہیں ہے، تو آپ ایک آسان فارم استعمال کر سکتے ہیں۔

my_round_int = lambda x: int((x * 2 + 1) // 2)

اگر آپ کو درست ہونے کی ضرورت ہے تو، اعشاریہ استعمال کرنا زیادہ محفوظ ہے۔

مندرجہ ذیل صرف حوالہ کے لیے ہے۔

ہندسوں کی کسی بھی تعداد تک اعشاریہ کو گول کریں۔

print(int(my_round(f)))
# 123

print(my_round_int(f))
# 123

print(my_round(f, 1))
# 123.5

print(my_round(f, 2))
# 123.46

راؤنڈ کے برعکس، 0.5 عام راؤنڈنگ کے مطابق 1 بن جاتا ہے۔

print(int(my_round(0.4)))
print(int(my_round(0.5)))
print(int(my_round(0.6)))
# 0
# 1
# 1

ہندسوں کی کسی بھی تعداد میں مکمل عدد

i = 99518

print(int(my_round(i, -1)))
# 99520

print(int(my_round(i, -2)))
# 99500

print(int(my_round(i, -3)))
# 100000

راؤنڈ کے برعکس، 5 عام راؤنڈنگ کے مطابق 10 بن جاتا ہے۔

print(int(my_round(4, -1)))
print(int(my_round(5, -1)))
print(int(my_round(6, -1)))
# 0
# 10
# 10

نوٹ: منفی اقدار کے لیے

مندرجہ بالا مثال کے فنکشن میں، -0.5 کو 0 پر گول کیا گیا ہے۔

print(int(my_round(-0.4)))
print(int(my_round(-0.5)))
print(int(my_round(-0.6)))
# 0
# 0
# -1

منفی قدروں کو گول کرنے کے بارے میں سوچنے کے مختلف طریقے ہیں، لیکن اگر آپ -0.5 کو -1 میں بنانا چاہتے ہیں، تو آپ اس میں مندرجہ ذیل ترمیم کر سکتے ہیں، مثال کے طور پر

import math

def my_round2(val, digit=0):
    p = 10 ** digit
    s = math.copysign(1, val)
    return (s * val * p * 2 + 1) // 2 / p * s

print(int(my_round2(-0.4)))
print(int(my_round2(-0.5)))
print(int(my_round2(-0.6)))
# 0
# -1
# -1
Copied title and URL