পাইথন অনন্ত - কোন সতর্কতা?


178

সুতরাং পাইথনের ইতিবাচক এবং নেতিবাচক অসীমতা রয়েছে:

float("inf"), float("-inf")

এটি কেবল বৈশিষ্ট্যের ধরণের মতো মনে হচ্ছে যাতে কিছুটা সতর্কতা থাকতে হবে। আমার কি সচেতন হওয়া উচিত?


25
নোট করুন ধ্রুবক 1e309হিসাবে ব্যাখ্যা করা হবে +infএবং হিসাবে ব্যাখ্যা করা -1e309হবে -inf
ক্রিস টেলর

উত্তর:


97

জড়িত সরল পাটিগণিত থেকে আপনি এখনও নং-অ-সংখ্যা (NaN) মান পেতে পারেন inf:

>>> 0 * float("inf")
nan

নোট করুন যে আপনি সাধারনত পাটিগণিত গণনার মাধ্যমে কোনও মান পাবেন নাinf :

>>> 2.0**2
4.0
>>> _**2
16.0
>>> _**2
256.0
>>> _**2
65536.0
>>> _**2
4294967296.0
>>> _**2
1.8446744073709552e+19
>>> _**2
3.4028236692093846e+38
>>> _**2
1.157920892373162e+77
>>> _**2
1.3407807929942597e+154
>>> _**2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')

infমান অস্বাভাবিক শব্দার্থবিদ্যা সঙ্গে একটি খুব বিশেষ মান বিবেচনা করা হয়, তাই এটি একটি সম্পর্কে জানতে ভালো OverflowErrorসোজা একটি ব্যতিক্রম মাধ্যমে দূরে, বরং একটি থাকার চেয়ে infচুপটি আপনার গণনার মধ্যে ইনজেকশনের মান।


8
একটি সাধারণ ভাসা সংযোজন, গুণ, ইত্যাদি আনন্দের সাথে ইনফ উত্পাদন করবে: এফ = 1.3407807929942597e + 154; f * f => inf। এটি একটি ওভারফ্লো ইরর বাড়াতে ** ব্যতিক্রম বলে মনে হচ্ছে।
অরেগন

@ ইরেগন, আসলে, **একটি বাচ্চা বগী বলে মনে হচ্ছে। যখন এটি আসল সংখ্যার সাথে উপচে পড়ে, এটি একটি ত্রুটি নিক্ষেপ করে, তবে যখন এর কোনও অপারেশন হয় infবা হয় -inf, এটি হয় হয় 0.0অথবা ফিরে আসে inf। সুতরাং ইনপুটটি স্বতন্ত্র থাকা অবস্থায় এটি সঠিকভাবে কাজ করে তবে ফলাফল অনন্ত হওয়া উচিত নয়।
আবেল

2
@ আবেল এটি বগি নয়। উপচে পড়া মানে সংখ্যাটি খুব বড়। এটি উপস্থাপনের জন্য খুব বড়, তবে এখনও অনন্তের চেয়ে অনেক ছোট। আপনার নির্দিষ্ট অ্যাপ্লিকেশন যুক্তির ব্যতিক্রম হ্যান্ডলারের পক্ষে এমন জায়গায় অনন্তটি স্থাপন করা কার্যকর হতে পারে তবে পাইথনের পক্ষে এটি সাধারণত ভুল হবে।
লুৎজ প্রেশেল্ট

6
@ লুটজ যদি এটির গুণগতরূপে আসে তবে এটি এখনও বেমানান আচরণ। অবশ্যই বড় * বড় হয় অনন্ত নয়।
রিচার্ড রাস্ট 23

100

পাইথনের বাস্তবায়ন আইইইই-75 75৪ মানকে অনুসরণ করে , যা আপনি দিকনির্দেশনা হিসাবে ব্যবহার করতে পারেন তবে এটি অন্তর্নিহিত সিস্টেমের উপর নির্ভর করে যা এটি সংকলিত হয়েছিল, তাই প্ল্যাটফর্মের পার্থক্য দেখা দিতে পারে। সম্প্রতি¹, একটি স্থিরতা প্রয়োগ করা হয়েছে যা "অনন্ত" পাশাপাশি "ইনফ" করতে দেয় তবে এটি এখানে সামান্য গুরুত্বপূর্ণ।

নিম্নলিখিত বিভাগগুলি যে কোনও ভাষার ক্ষেত্রে সমানভাবে প্রযোজ্য যা আইইইই ভাসমান পয়েন্ট গণিতকে সঠিকভাবে প্রয়োগ করে, এটি কেবল পাইথনের ক্ষেত্রে নির্দিষ্ট নয়।

অসমতা জন্য তুলনা

অপারেটরের সাথে এবং অপারেটরগুলির >চেয়ে বেশি বা কম-এর সাথে লেনদেন করার সময় <, নিম্নলিখিত বিষয়গুলি গণনা করা হয়:

  • সহ +infযে কোনও সংখ্যা এর চেয়ে বেশি-inf
  • সহ -infযে কোনও সংখ্যা তার চেয়ে কম is+inf
  • +infএর চেয়ে উচ্চতর বা কম নয়+inf
  • -inf এর চেয়ে উচ্চতর বা কম নয় -inf
  • জড়িত NaNযে কোনও তুলনা মিথ্যা ( infউচ্চতর বা কম নয় NaN)

সমতার জন্য তুলনা

যখন সমতার জন্য তুলনা করা হয়, +infএবং +infসমান, যেমন হয় -infএবং হয় -inf। এটি অনেক বিতর্কিত সমস্যা এবং এটি আপনার কাছে বিতর্কিত হতে পারে তবে এটি আইইইই স্ট্যান্ডার্ডে রয়েছে এবং পাইথন ঠিক সেভাবে আচরণ করে।

অবশ্যই, +infঅসম -infএবং NaNনিজেকে সহ সমস্ত কিছু অসম NaN

অনন্ত সহ গণনা

অসীমের সাথে সর্বাধিক গণনাগুলি অসীমতা অর্জন করবে, যদি না উভয় অপারেশন অনন্ত হয়, যখন অপারেশন বিভাগ বা মডুলো বা শূন্যের সাথে গুণ সহ, কিছু বিশেষ নিয়ম মাথায় রাখতে হয়:

  • যখন শূন্য দ্বারা গুণিত হয়, যার ফলস্বরূপ অপরিজ্ঞাত হয়, ফলন হয় NaN
  • যখন কোনও সংখ্যা (অনন্ত নিজেই বাদে) অনন্ত দ্বারা বিভাজন করা হয়, যা ফল দেয় 0.0বা -0.0² ²
  • ধনাত্মক বা নেতিবাচক অসীম দ্বারা ধনাত্মক বা নেতিবাচক অনন্তকে বিভাজন (মডুলো সহ) ভাগ করার সময়, ফলাফলটি অনির্ধারিত হয়, তাই NaN
  • বিয়োগ করার সময়, ফলাফলগুলি বিস্ময়কর হতে পারে, তবে সাধারণ গণিত জ্ঞানের অনুসরণ করুন :
    • যখন করছেন inf - inf, ফলে অনির্ধারিত হল: NaN;
    • যখন করছেন inf - -inf, ফলাফল হয় inf;
    • যখন করছেন -inf - inf, ফলাফল হয় -inf;
    • যখন করছেন -inf - -inf, ফলে অনির্ধারিত হল: NaN
  • যোগ করার সময়, এটি একইভাবে আশ্চর্যজনকও হতে পারে:
    • যখন করছেন inf + inf, ফলাফল হয় inf;
    • যখন করছেন inf + -inf, ফলে অনির্ধারিত হল: NaN;
    • যখন করছেন -inf + inf, ফলে অনির্ধারিত হল: NaN;
    • যখন করছেন -inf + -inf, ফলাফল হয় -inf
  • ব্যবহার করা math.pow, powবা **কৌশলপূর্ণ, এটি যেমনটি করা উচিত তেমন আচরণ করে না। এটি একটি ওভারফ্লো ব্যতিক্রম দুটি বাস্তব সংখ্যার ফলাফলের খুব ডবল স্পষ্টতা ভাসা (এটা অনন্ত আসতে উচিত) মাপসই উচ্চ ছোঁড়ার, কিন্তু ইনপুট infবা -inf, এটি সঠিকভাবে এবং আয় পারেন আচরণ করবে infবা 0.0। দ্বিতীয় আর্গুমেন্টটি যখন হয় NaN, এটি NaNপ্রথম তর্ক না করে ফিরে আসে 1.0। আরও কিছু সমস্যা রয়েছে, সমস্ত দস্তাবেজে আবদ্ধ নয় ।
  • math.expহিসাবে একই সমস্যা ভোগা math.pow। ওভারফ্লোর জন্য এটি ঠিক করার একটি সমাধান হল এর অনুরূপ কোড ব্যবহার করা:

    try:
        res = math.exp(420000)
    except OverflowError:
        res = float('inf')

মন্তব্য

নোট 1: অতিরিক্ত সতর্কতা হিসাবে, আইইইই স্ট্যান্ডার্ড দ্বারা সংজ্ঞায়িত হিসাবে, যদি আপনার গণনাটি ফলাফলের নীচে বা অতিরিক্ত প্রবাহিত হয় তবে ফলাফলটি কোনও আন্ডার-ওভারফ্লো ত্রুটি হবে না, তবে ইতিবাচক বা নেতিবাচক অনন্ত: 1e308 * 10.0ফলন হবে inf

দ্রষ্টব্য 2: যেহেতু NaNরিটার্ন সহ কোনও গণনা NaNএবং নিজের সাথে কোনও তুলনা হ'ল , কোনও সংখ্যা সত্যই কিনা তা নির্ধারণ করার জন্য আপনার ফাংশনটি ব্যবহার করা উচিত ।NaNNaNfalsemath.isnanNaN

নোট 3: যদিও পাইথন লেখার পক্ষে সমর্থন করে float('-NaN')তবে চিহ্নটি উপেক্ষা করা হয়, কারণ NaNঅভ্যন্তরীণভাবে কোনও চিহ্ন নেই । আপনি বিভক্ত হলে -inf / +inf, ফলাফল NaN, না -NaN(যেমন কিছু আছে)।

নোট 4: উপরের যে কোনওটির উপর নির্ভর করার জন্য সতর্ক থাকুন, যেহেতু পাইথন সি বা জাভা লাইব্রেরির উপর নির্ভর করে এটি সমস্ত অন্তর্নিহিত সিস্টেমগুলি এই আচরণটি সঠিকভাবে প্রয়োগ করে না এবং এটি সিলেক্ট করা হয়েছিল। আপনি যদি নিশ্চিত হতে চান, আপনার গণনা করার আগে অনন্তের জন্য পরীক্ষা করুন।

¹) সাম্প্রতিকতম অর্থ সংস্করণ ৩.২ থেকে
²) ভাসমান পয়েন্টগুলি ধনাত্মক এবং নেতিবাচক শূন্যকে সমর্থন করে, সুতরাং: x / float('inf')এর চিহ্ন রাখে এবং -1 / float('inf')ফলন দেয় -0.0, 1 / float(-inf)ফলন দেয় -0.0, 1 / float('inf')ফলন দেয় 0.0এবং -1/ float(-inf)ফলন দেয় 0.0। এছাড়াও, 0.0 == -0.0হ'লtrue , যদি আপনি সত্যটি না চান তবে আপনাকে স্বাক্ষরটি নিজেই পরীক্ষা করতে হবে।


11
একটি ছোট্ট নিটপিক: অনন্তর সহ প্রতিটি গণনা অনন্ত ফলন দেয় না:-1 * float('infinity') == -inf
ইভান কোলে

4
সে কারণেই আমি বলেছিলাম এটি একটি ছোট্ট নিটপিক। আপনি আমাকে এক মিনিটের জন্য চিন্তিত করেছিলেন যে অনন্তের সাথে কাজ করার সময় এই চিহ্নটি সম্পূর্ণ উপেক্ষা করা হবে এবং আমি অন্য ব্যক্তির পক্ষে স্পষ্ট করতে চাই।
ইভান ক্রোল

12
ভাল, প্রায়: 1 / ভাসা ('অনন্ত') == 0.0
ফিল

3
@ ফিল: যদিও আমি পুরোপুরি নিশ্চিত যে আপনি কেবল দেখানোর চেষ্টা করছেন যে ইনফ বা না-এন-এর ফলাফলের সাথে সমস্ত হিসাব নেই, তবে আমি অন্যদের কাছে কেবল এটি স্পষ্ট করে জানাতে চেয়েছিলাম যে মন্তব্যগুলির মাধ্যমে পড়তে পারে, যে 1 / ভাসা ('অনন্ত) ') == 0.0 সত্য; কারণ, আপনি যেমন অনন্তের কাছে পৌঁছে যাচ্ছেন, বিভাগের ফলাফল 0 পৌঁছেছে I আমি জানি এটি কেবলমাত্র মৌলিক ক্যালকুলাস, তবে আমি নিশ্চিত হতে চেয়েছিলাম যে এই পাঠকরা বুঝতে পেরেছেন, বা কমপক্ষে কোনও কারণ আছে কেন, ফলাফলটি কী তা বোঝা উচিত।
অ্যান্থনি পেস

1
আমার অনুভূতি আছে যে এই উত্তরটি গৃহীত উত্তরের চেয়ে অনেক ভাল।
খ্রিস্টান হেরেনজ

3

সুতরাং করে C99

সমস্ত আধুনিক প্রসেসর দ্বারা ব্যবহৃত আইইইই 754 ফ্লোটিং পয়েন্ট উপস্থাপনার বেশ কয়েকটি বিশেষ বিট নিদর্শন রয়েছে ধনাত্মক অসীমের জন্য সংরক্ষিত (চিহ্ন = 0, এক্সপ্রেস = (0, frac = 0), নেতিবাচক অনন্ত (চিহ্ন = 1, এক্সপ্রেস = ~ 0, frac = 0 ), এবং অনেক NaN (কোনও সংখ্যা নয়: exp = ~ 0, frac ≠ 0)।

আপনার যে সমস্ত বিষয়ে চিন্তা করতে হবে: কিছু গাণিতিকগুলি ভাসমান পয়েন্ট ব্যতিক্রম / ফাঁদ পেতে পারে, তবে সেগুলি কেবল এই "আকর্ষণীয়" ধ্রুবকের মধ্যে সীমাবদ্ধ নয়।


1
সুতরাং আমার গাণিতিকটি যদি খুব বড় হয় তবে এটি একটি ইনফ হয়ে যেতে পারে?
কেসব্যাশ

@ ক্যাসবাশ নং, এটির কারণ হবে OverflowError
wizzwizz4

2

আমি একটি সতর্কতামূলক সন্ধান পেয়েছি যা এখনও পর্যন্ত কেউ উল্লেখ করেনি। আমি জানি না এটি প্রায়শই ব্যবহারিক পরিস্থিতিতে আসে কিনা, তবে এখানে এটি সম্পূর্ণতার জন্য।

সাধারণত, একটি সংখ্যার মডুলো অনন্ত গণনা করা নিজেকে ভাসমান হিসাবে ফিরিয়ে দেয় তবে ভগ্নাংশের মডুলো ইনফিনিটি ফিরে আসে nan(কোনও সংখ্যা নয়)। এখানে একটি উদাহরণ:

>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan

পাইথন বাগ ট্র্যাকারে আমি একটি সমস্যা দায়ের করেছি। এটি https://bugs.python.org/issue32968 এ দেখা যাবে ।

আপডেট: এটি পাইথন 3.8 এ স্থির করা হবে ।


2

একটি খুব খারাপ আবরণ: জিরো দ্বারা বিভাগ

একটি 1/xভগ্নাংশ, পর্যন্ত x = 1e-323এটা infকিন্তু যখন x = 1e-324বা সামান্য এটা ছোঁড়ারZeroDivisionError

>>> 1/1e-323
inf

>>> 1/1e-324
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero

তাই সাবধান!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.