পাইথনে 1 // 0.01 == 99 কেন?


31

আমি কল্পনা করি এটি একটি ক্লাসিক ভাসমান পয়েন্ট নির্ভুলতা প্রশ্ন, তবে আমি 1//0.01পাইথন ৩.7.৫ ফলন দিয়ে চালিয়ে এই ফলাফলটির চারপাশে আমার মাথা গুটিয়ে দেওয়ার চেষ্টা করছি 99

আমি ধারণা করি এটি একটি প্রত্যাশিত ফলাফল, তবে এটির int(1/f)পরিবর্তে কখন ব্যবহার করা নিরাপদ তা সিদ্ধান্ত নেওয়ার কোনও উপায় আছে 1//f?


4
হ্যাঁ, এটি সর্বদা নিরাপদ হয় (1 / চ)। কেবলমাত্র // এটি একটি সম্পূর্ণ বিভাগ, এবং আপনি ভুলভাবে এটিকে রাউন্ড হিসাবে ভাবেন।
পেরডি এস্তাকুয়েল


2
সদৃশ নয়। এটি সর্বদা round()এবং কখনই //বা ব্যবহার করে 99.99% প্রত্যাশিত হিসাবে কাজ করতে পারে int()। লিঙ্কিত প্রশ্নটি ভাসমান তুলনার সাথে কাটছাঁটির সাথে কিছুই করার নেই এবং এ জাতীয় কোনও সহজ সমাধান নেই।
ম্যাক্সি

উত্তর:


23

এটি যদি আসল সংখ্যার সাথে বিভাজন 1//0.01হত তবে তা 0.01হ'ল 100। 99 এ।


3
এটি "কখন নিরাপদ হবে" সিদ্ধান্ত নেওয়ার কোনও উপায় আছে তা এই অংশটিকে সম্বোধন করে না।
স্কট হান্টার

10
"নিরাপদ" সঠিকভাবে সংজ্ঞায়িত করা হয়নি।
চিপনার

1
এটিকে পুরোপুরি উপেক্ষা করার জন্য যথেষ্ট e ওপি যখন ভাসমান বিষয় সম্পর্কিত বিষয় সম্পর্কে সচেতন?
স্কট হান্টার

3
@ চেপনার যদি "নিরাপদ" যথাযথভাবে সংজ্ঞায়িত না হয় তবে স্পষ্টতার জন্য জিজ্ঞাসা করা আরও ভাল: /

2
এটি আমার কাছে বেশ স্পষ্ট যে "নিরাপদ" অর্থ "ত্রুটি একটি সস্তা পকেট ক্যালকুলেটরের চেয়ে খারাপ নয়"
ম্যাক্সি

9

এই ফলাফলের কারণগুলি আপনার বক্তব্যের মতো এবং এগুলি ব্যাখ্যা করা হয়েছে যে ভাসমান পয়েন্টের গণিতটি ভেঙে গেছে? এবং অন্যান্য অনেক অনুরূপ প্রশ্নোত্তর।

আপনি যখন অঙ্ক এবং ডিনোমিনেটরের দশমিকের সংখ্যা জানেন, তখন আরও নির্ভরযোগ্য উপায় হ'ল প্রথমে এই সংখ্যাগুলিকে গুণ করা যাতে তারা পূর্ণসংখ্যার হিসাবে বিবেচনা করতে পারে এবং তারপরে তাদের উপর পূর্ণসংখ্যা বিভাগ সম্পাদন করতে পারে:

সুতরাং আপনার ক্ষেত্রে 1//0.01প্রথমে রূপান্তর করা উচিত 1*100//(0.01*100)যা 100 হয়।

আরও চরম ক্ষেত্রে আপনি এখনও "অপ্রত্যাশিত" ফলাফল পেতে পারেন। roundপূর্ণসংখ্যা বিভাগ সম্পাদনের আগে সংখ্যক এবং ডিনমিনেটরে একটি কল যুক্ত করার প্রয়োজন হতে পারে :

1 * 100000000000 // round(0.00000000001 * 100000000000)

তবে, যদি এটি স্থির দশমিক (অর্থ, সেন্ট) দিয়ে কাজ করার বিষয়ে হয়, তবে সেন্টের সাথে ইউনিট হিসাবে কাজ করার কথা বিবেচনা করুন , যাতে সমস্ত পাটিগণিত পূর্ণসংখ্যার গাণিতিক হিসাবে করা যায় এবং করার সময় কেবলমাত্র মুদ্রা ইউনিট (ডলার) থেকে রূপান্তরিত হয় doing ইনপুট / আউটপুট।

অথবা বিকল্পভাবে, দশমিক জন্য একটি লাইব্রেরি মত ব্যবহার দশমিক , যা:

... দ্রুত সঠিকভাবে গোলাকার দশমিক ভাসমান পয়েন্ট গণিতের জন্য সমর্থন সরবরাহ করে।

from decimal import Decimal
cent = Decimal(1) / Decimal(100) # Contrary to floating point, this is exactly 0.01
print (Decimal(1) // cent) # 100

3
"যা স্পষ্টতই 100।" অগত্যা নয়: যদি .01 সঠিক না হয়, তবে .01 * 100 পাশাপাশি হয় না। এটি ম্যানুয়ালি "টিউন" করতে হবে।
glglgl

8

আপনি কি একাউন্টে নিতে হবে যে //হয় floorঅপারেটর এবং যেমন আপনি যদি প্রথম মনে যেন আপনি সমান সম্ভাবনা 99 হিসেবে 100 পড়া থাকা উচিত (*) (কারণ অপারেশন হবে 100 ± epsilonসঙ্গে epsilon>0প্রদান করা যে ঠিক 100.00 পাবার সম্ভাবনা ..0 অত্যন্ত কম।)

আপনি আসলে এটি একটি বিয়োগ চিহ্ন দিয়ে দেখতে পারেন,

>>> 1//.01
99.0
>>> -1//.01
-100.0

এবং আপনার অবাক হওয়া উচিত।

অন্যদিকে, int(-1/.01)প্রথমে বিভাগ সম্পাদন করে এবং তারপর int()সংখ্যায় প্রয়োগ করে , যা মেঝে নয় বরং 0 এর দিকে কাটা ! অর্থ এই ক্ষেত্রে,

>>> 1/.01
100.0
>>> -1/.01
-100.0

অত: পর,

>>> int(1/.01)
100
>>> int(-1/.01)
-100

যদিও গোলাকার, আপনাকে এই অপারেটরের জন্য আপনার প্রত্যাশিত ফলাফল দেবে কারণ আবার, ত্রুটিটি সেই পরিসংখ্যানগুলির জন্য ছোট।

(*) আমি বলছি না যে সম্ভাবনা একই রকম, আমি কেবল বলছি যে আপনি যখন ভাসমান গাণিতিকের সাথে এমন একটি গণনা করেন যা আপনি কী পাচ্ছেন তার একটি অনুমান।


7

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

দশমিক বা ভগ্নাংশে কাস্ট করে আপনি ভাসমান পয়েন্ট সংখ্যাটির সঠিক মান দেখতে পাবেন।

>>> from decimal import Decimal
>>> Decimal(0.01)
Decimal('0.01000000000000000020816681711721685132943093776702880859375')
>>> from fractions import Fractio
>>> Fraction(0.01)
Fraction(5764607523034235, 576460752303423488) 

আমাদের অযোগ্য আক্ষরিক কারণে ত্রুটিটি খুঁজে পেতে আমরা ভগ্নাংশ প্রকারটি ব্যবহার করতে পারি।

>>> float((Fraction(1)/Fraction(0.01)) - 100)
-2.0816681711721685e-15

আমরা 100 টির কাছাকাছি দানাদার ডাবল নির্ভুলতা ভাসমান পয়েন্ট সংখ্যাগুলি নমপির পরবর্তীটি ব্যবহার করে এটি জানতে পারি।

>>> from numpy import nextafter
>>> nextafter(100,0)-100
-1.4210854715202004e-14

এটি থেকে আমরা অনুমান করতে পারি যে নিকটতম ভাসমান পয়েন্ট সংখ্যাটি 1/0.01000000000000000020816681711721685132943093776702880859375আসলে 100 টি।

1//0.01এবং এর মধ্যে পার্থক্যটি int(1/0.01)গোলাকার। 1 // 0.01 একক পদক্ষেপে পরবর্তী পুরো সংখ্যায় সঠিক ফলাফলটিকে গোল করে। সুতরাং আমরা 99 এর ফলাফল পেয়েছি।

অন্যদিকে int (1 / 0.01) দুটি পর্যায়ে গোল করে, প্রথমে ফলাফলটি নিকটতম ডাবল নির্ভুলতা ভাসমান পয়েন্ট সংখ্যাটি (যা হ'ল 100) গোল করে, তারপরে এটি গোল করে যে ভাসমান পয়েন্ট সংখ্যাটি পরবর্তী সংখ্যার নীচে (যা হয়) আবার ঠিক 100)।


এটিকে কেবল রাউন্ডিং বলা বিভ্রান্তিকর। এটি হয় বলা উচিত ছাঁটাই বা শূন্য প্রতি rounding : int(0.9) == 0এবংint(-0.9) == 0
Maxy

এটি বাইনারি ভাসমান পয়েন্ট ধরণের যা আপনি এখানে বলছেন। (দশমিক ভাসমান পয়েন্টের ধরণগুলিও রয়েছে))
স্টিফেন সি

3

আপনি যদি নিম্নলিখিতটি কার্যকর করেন

from decimal import *

num = Decimal(1) / Decimal(0.01)
print(num)

আউটপুটটি হবে:

99.99999999999999791833182883

এটি এভাবে অভ্যন্তরীণভাবে উপস্থাপিত হয়, সুতরাং এটিকে গোল করে দেওয়া //হবে99


2
এই ক্ষেত্রে ত্রুটিটি দেখানোর পক্ষে এটি যথেষ্ট সঠিক তবে সচেতন থাকবেন যে "দশমিক" গাণিতিকটিও ঠিক নয়।
প্লাগওয়াশ

আপনার সাথে Decimal(0.01)অনেক দেরি হয়ে গেছে, আপনি কল করার আগেই ত্রুটিটি ইতিমধ্যে প্রবেশ করেছে Decimal। আমি নিশ্চিত নই যে এটি কীভাবে প্রশ্নের উত্তর, ... আপনাকে অবশ্যই প্রথমে একটি নির্ভুল 0.01 গণনা করতে হবে Decimal(1) / Decimal(100), যেমন আমি আমার উত্তরে দেখিয়েছি।
ট্রাইঙ্কট

@ ট্রিনকোট আমার উত্তর "কেন 1 // 0.01 == 99" শিরোনামের প্রশ্নের উত্তরটিতে আমি ওপিকে দেখানোর চেষ্টা করেছি যে ভাসমান সংখ্যাগুলি অভ্যন্তরীণভাবে কীভাবে আচরণ করা হয়।
বৃষ্টি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.