मैं चाहता हूँ a
करने के लिए गोल होने के लिए 13.95 ।
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
round
समारोह तरह से मैं उम्मीद काम नहीं करता।
मैं चाहता हूँ a
करने के लिए गोल होने के लिए 13.95 ।
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
round
समारोह तरह से मैं उम्मीद काम नहीं करता।
जवाबों:
आप पुरानी समस्या में भाग रहे हैं फ़्लोटिंग पॉइंट नंबरों के साथ कि सभी नंबरों का प्रतिनिधित्व बिल्कुल नहीं किया जा सकता है। कमांड लाइन बस आपको मेमोरी से पूर्ण फ़्लोटिंग पॉइंट फॉर्म दिखा रही है।
फ्लोटिंग पॉइंट प्रतिनिधित्व के साथ, आपका गोल संस्करण समान संख्या है। चूंकि कंप्यूटर द्विआधारी हैं, वे एक पूर्णांक के रूप में फ्लोटिंग पॉइंट नंबर संग्रहीत करते हैं और फिर इसे दो की शक्ति से विभाजित करते हैं इसलिए 13.95 को 125650429603636838 / (2 ** 53) के समान फैशन में प्रतिनिधित्व किया जाएगा।
डबल सटीक संख्याओं में 53 बिट्स (16 अंक) सटीक और नियमित फ़्लोट्स में 24 बिट्स (8 अंक) सटीक होते हैं। अजगर में चल बिन्दु प्रकार पर दो परिशुद्धता का उपयोग करता है मान संग्रहीत करने के लिए।
उदाहरण के लिए,
>>> 125650429603636838/(2**53)
13.949999999999999
>>> 234042163/(2**24)
13.949999988079071
>>> a = 13.946
>>> print(a)
13.946
>>> print("%.2f" % a)
13.95
>>> round(a,2)
13.949999999999999
>>> print("%.2f" % round(a, 2))
13.95
>>> print("{:.2f}".format(a))
13.95
>>> print("{:.2f}".format(round(a, 2)))
13.95
>>> print("{:.15f}".format(round(a, 2)))
13.949999999999999
यदि आप केवल दो दशमलव स्थानों (उदाहरण के लिए एक मुद्रा मूल्य प्रदर्शित करने के लिए) के बाद हैं, तो आपके पास कुछ बेहतर विकल्प हैं:
"%.2f" % round(a,2)
आप न केवल str()
float
) दशमलव संख्या का केवल निकटतम उपलब्ध सन्निकटन है (जो आप एक इंसान के रूप में परिचित हैं)। 0.245 के रूप में ऐसा (अंतिम रूप से प्रतिनिधित्व योग्य) द्विआधारी मूल्य नहीं है। यह बस अस्तित्व में नहीं है, और गणितीय रूप से मौजूद नहीं हो सकता है। बाइनरी मान जो 0.245 के सबसे करीब है, वह 0.245 से थोड़ा कम है , इसलिए स्वाभाविक रूप से यह गोल हो जाता है। इसी तरह, बाइनरी में 0.225 जैसी कोई चीज नहीं है, लेकिन बाइनरी वैल्यू जो 0.225 के सबसे करीब है, 0.225 से थोड़ा अधिक है , इसलिए स्वाभाविक रूप से यह गोल हो जाता है।
Decimal
, और इस उत्तर में प्रस्तुत समाधानों में से एक था। दूसरा था अपनी मात्राओं को पूर्णांक में बदलना और पूर्णांक अंकगणित का उपयोग करना। ये दोनों दृष्टिकोण अन्य उत्तरों और टिप्पणियों में भी दिखाई दिए।
नए प्रारूप विनिर्देश हैं, स्ट्रिंग प्रारूप विशिष्टता मिनी-भाषा :
आप ऐसा कर सकते हैं:
"{:.2f}".format(13.949999999999999)
नोट 1: उपरोक्त रिटर्न एक स्ट्रिंग है। फ्लोट के रूप में प्राप्त करने के लिए, बस इसके साथ लपेटें float(...)
:
float("{:.2f}".format(13.949999999999999))
नोट 2: के साथ लपेटकर float()
कुछ भी नहीं बदलता है:
>>> x = 13.949999999999999999
>>> x
13.95
>>> g = float("{:.2f}".format(x))
>>> g
13.95
>>> x == g
True
>>> h = round(x, 2)
>>> h
13.95
>>> x == h
True
'{0:,.2f}'.format(1333.949999999)
प्रिंट कर सकते हैं '1,333.95'
।
float()
; float("{0:.2f}".format(13.9499999))
f"Result is {result:.2f}"
बिल्ट-इन round()
काम करता है ठीक पायथन 2.7 या बाद में।
उदाहरण:
>>> round(14.22222223, 2)
14.22
की जाँच करें प्रलेखन ।
round(2.16, 1)
देना 2.2
क्यों अजगर सिर्फ एक की पेशकश truncate
समारोह
>>> round(2.675, 2) 2.67
डॉक्सहोमथोन.org
Note The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float.
मुझे लगता है कि सबसे सरल दृष्टिकोण format()
फ़ंक्शन का उपयोग करना है।
उदाहरण के लिए:
a = 13.949999999999999
format(a, '.2f')
13.95
यह दो दशमलव बिंदुओं पर गोल स्ट्रिंग के रूप में एक फ्लोट संख्या पैदा करता है।
उपयोग
print"{:.2f}".format(a)
के बजाय
print"{0:.2f}".format(a)
क्योंकि बाद में कई चर का उत्पादन करने की कोशिश करते समय आउटपुट त्रुटियां हो सकती हैं (टिप्पणियां देखें)।
अधिकांश संख्याएँ फ़्लोट्स में बिलकुल नहीं दर्शाई जा सकतीं। यदि आप संख्या को गोल करना चाहते हैं, क्योंकि आपके गणितीय सूत्र या एल्गोरिथ्म की आवश्यकता है, तो आप गोल का उपयोग करना चाहते हैं। यदि आप केवल एक निश्चित परिशुद्धता के लिए प्रदर्शन को प्रतिबंधित करना चाहते हैं, तो गोल का भी उपयोग न करें और इसे केवल उस स्ट्रिंग के रूप में प्रारूपित करें। (यदि आप इसे कुछ वैकल्पिक गोलाई पद्धति के साथ प्रदर्शित करना चाहते हैं, और टन हैं, तो आपको दोनों दृष्टिकोणों को मिलाना होगा।)
>>> "%.2f" % 3.14159
'3.14'
>>> "%.2f" % 13.9499999
'13.95'
और अंत में, हालांकि शायद सबसे महत्वपूर्ण बात, अगर आप सटीक गणित चाहते हैं तो आप बिल्कुल भी तैरना नहीं चाहते हैं। सामान्य उदाहरण पैसे के साथ काम कर रहा है और 'सेंट' को पूर्णांक के रूप में संग्रहीत करना है।
नीचे दिए गए कोड को आज़माएं:
>>> a = 0.99334
>>> a = int((a * 100) + 0.5) / 100.0 # Adding 0.5 rounds it up
>>> print a
0.99
round
पहले स्थान पर फ़ंक्शन का उपयोग करके ऐसा करने का कोई लाभ नहीं है। एक और बात के लिए, क्योंकि यह समाधान अभी भी फ्लोटिंग पॉइंट का उपयोग करता है, ओपी की मूल समस्या बनी हुई है, यहां तक कि इस "समाधान" के "सही" संस्करण के लिए भी।
round
फ़ंक्शन का एक अनावश्यक कार्यान्वयन है (जिसका उपयोग प्रश्न में किया गया था)।
round()
ओपी के बताए अनुसार काम नहीं करता है।
इनपुट / आउटपुट की राउंडिंग समस्या को निश्चित रूप से अजगर 2.7.0 और 3.1 द्वारा हल किया गया है ।
एक सही ढंग से गोल संख्या को पीछे और पीछे से परिवर्तित किया जा सकता है:
str -> float() -> repr() -> float() ...
या Decimal -> float -> str -> Decimal
भंडारण के लिए एक दशमलव प्रकार अब आवश्यक नहीं है।
(स्वाभाविक रूप से, संचित अंतिम बिट त्रुटियों को समाप्त करने के लिए गोल संख्याओं के जोड़ या घटाव के परिणामस्वरूप गोल करना आवश्यक हो सकता है। एक स्पष्ट दशमलव अंकगणित अभी भी उपयोगी हो सकता है, लेकिन स्ट्रिंग द्वारा रूपांतरण str()
(जो कि 12 मान्य अंकों के चक्कर के साथ है। ) पर्याप्त रूप से अच्छा है अगर कोई चरम सटीकता या क्रमिक अंकगणित संचालन की कोई चरम संख्या की आवश्यकता नहीं है।)
अनंत परीक्षण :
import random
from decimal import Decimal
for x in iter(random.random, None): # Verify FOREVER that rounding is fixed :-)
assert float(repr(x)) == x # Reversible repr() conversion.
assert float(Decimal(repr(x))) == x
assert len(repr(round(x, 10))) <= 12 # Smart decimal places in repr() after round.
if x >= 0.1: # Implicit rounding to 12 significant digits
assert str(x) == repr(round(x, 12)) # by str() is good enough for small errors.
y = 1000 * x # Decimal type is excessive for shopping
assert str(y) == repr(round(y, 12 - 3)) # in a supermaket with Python 2.7+ :-)
रिलीज़ नोट देखें पायथन 2.7 - अन्य भाषा चौथे पैराग्राफ को बदल देती है:
रूपांतरण फ्लोटिंग प्वाइंट नंबर और तार के बीच अब कर रहे हैं सही ढंग से गोल सबसे प्लेटफार्मों पर। ये रूपांतरण कई अलग-अलग जगहों पर होते हैं: फ़्लोट्स और जटिल संख्याओं पर str (); फ्लोट और जटिल निर्माणकर्ता; संख्यात्मक स्वरूपण; क्रमिक और डी-क्रमांकन तैरता है और जटिल संख्या का उपयोग करते हुए
marshal
,pickle
औरjson
मॉड्यूल; पायथन कोड में फ्लोट और काल्पनिक शाब्दिक का पार्सिंग; और दशमलव-से-फ्लोट रूपांतरण।इस से संबंधित, फ़्लोटिंग-पॉइंट नंबर x का repr () अब सबसे छोटा दशमलव स्ट्रिंग के आधार पर एक परिणाम देता है जो सही राउंडिंग (राउंड-हाफ-टू-एंड-राउंडिंग मोड के साथ) के तहत वापस राउंड टू एक्स की गारंटी है । पहले इसने x को 17 दशमलव अंकों के चक्कर के आधार पर दिया था।
अधिक जानकारी:float
पायथन 2.7 से पहले का प्रारूपण वर्तमान के समान था numpy.float64
। दोनों प्रकार 52 बिट mantissa के साथ 64 बिट IEEE 754 डबल परिशुद्धता का उपयोग करते हैं । एक बड़ा अंतर यह है कि स्वरूपित किया गया है ताकि हर अंक महत्वपूर्ण हो; अनुक्रम अंतराल के बिना है और रूपांतरण प्रतिवर्ती है। बस: यदि आपके पास शायद एक numpy.float64 नंबर है, तो इसे मनुष्यों के लिए स्वरूपित करने के लिए सामान्य फ्लोट में रूपांतरित करें, संख्यात्मक प्रोसेसर के लिए नहीं, अन्यथा पायथन 2.7+ के साथ अधिक कुछ भी आवश्यक नहीं है।np.float64.__repr__
अक्सर एक अत्यधिक दशमलव संख्या के साथ स्वरूपित किया जाता है ताकि कोई भी बिट खो न जाए, लेकिन कोई भी वैध IEEE 754 नंबर 13.949999999999 और 13.950000000000001 के बीच मौजूद नहीं है। परिणाम अच्छा नहीं है और रूपांतरण repr(float(number_as_string))
सुन्न के साथ प्रतिवर्ती नहीं है। दूसरी ओर:float.__repr__
float
(डबल सटीक) और सामान्य के round
बारे में था, न कि numpy.double और स्ट्रिंग में इसके रूपांतरण के बारे में। प्लेन पायथन राउंडिंग वास्तव में पायथन 2.7 से बेहतर नहीं किया जा सकता है। अधिकांश उत्तर 2.7 से पहले लिखे गए हैं, लेकिन वे मोटे हैं, हालांकि वे मूल रूप से बहुत अच्छे थे। यह मेरे उत्तर का कारण है।
1
कि "क्रमिक अंडरफ़्लो" के दौरान छोड़कर, निहित है ।
a*b
बनाम था b*a
। लिंक के लिए धन्यवाद - नॉस्टेल्जिया।
पायथन <3 (जैसे 2.6 या 2.7) के साथ, ऐसा करने के दो तरीके हैं।
# Option one
older_method_string = "%.9f" % numvar
# Option two (note ':' before the '.9f')
newer_method_string = "{:.9f}".format(numvar)
लेकिन ध्यान दें कि पायथन संस्करणों के लिए 3 से ऊपर (उदाहरण 3.2 या 3.3), विकल्प दो को प्राथमिकता दी जाती है ।
विकल्प दो के बारे में अधिक जानकारी के लिए, मैं पायथन प्रलेखन से स्ट्रिंग प्रारूपण पर इस लिंक का सुझाव देता हूं ।
और विकल्प एक पर अधिक जानकारी के लिए, यह लिंक पर्याप्त होगा और विभिन्न झंडों की जानकारी होगी ।
संदर्भ: फ्लोटिंग पॉइंट नंबर को एक निश्चित परिशुद्धता में बदलें, और फिर स्ट्रिंग पर कॉपी करें
numvar=12.456
, तो "{:.2f}".format(numvar)
पैदावार 12.46
लेकिन "{:2i}".format(numvar)
एक त्रुटि देता है और मैं उम्मीद कर रहा हूं 12
।
आप आउटपुट प्रारूप को संशोधित कर सकते हैं:
>>> a = 13.95
>>> a
13.949999999999999
>>> print "%.2f" % a
13.95
यहां किसी ने भी इसका उल्लेख नहीं किया है, इसलिए मुझे पायथन 3.6 के एफ-स्ट्रिंग / टेम्प्लेट-स्ट्रिंग प्रारूप में एक उदाहरण देना चाहिए, जो मुझे लगता है कि सुंदर रूप से साफ है:
>>> f'{a:.2f}'
यह लंबे उदाहरणों के साथ भी अच्छा काम करता है, परिचालकों के साथ और आवश्यकता नहीं है:
>>> print(f'Completed in {time.time() - start:.2f}s')
आप अजगर में 2 दशमलव स्थानों तक मूल्य को गोल करने के लिए प्रारूप ऑपरेटर का उपयोग कर सकते हैं :
print(format(14.4499923, '.2f')) // output is 14.45
पायथन 2.7 में:
a = 13.949999999999999
output = float("%0.2f"%a)
print output
output
के समान सटीक मान है a
, इसलिए आपने अंतिम पंक्ति के print a
बजाय लिखा हो सकता है print output
।
13.95
। लेकिन ऐसा करता है print a
, a
पायथन 2.7 में इस विशेष मूल्य के लिए , इसलिए यह वास्तव में स्पष्ट नहीं है कि प्रारूपण चरण का क्या मतलब था।
a == output
आपके द्वारा दिखाए गए कोड के लिए प्रयास किया था? यह True
मेरे लिए देता है, और मुझे संदेह है कि यह आपके लिए भी है।
पायथन ट्यूटोरियल में एक परिशिष्ट है जिसे फ्लोटिंग पॉइंट अरिथमेटिक कहा जाता है : मुद्दे और सीमाएं । इसे पढ़ें। यह बताता है कि क्या हो रहा है और क्यों पायथन अपना सर्वश्रेष्ठ प्रदर्शन कर रहा है। इसका एक उदाहरण और भी है जो आप से मेल खाता है। मुझे थोड़ा उद्धृत करें:
>>> 0.1 0.10000000000000001
हो सकता है कि आप
round()
फंक्शन का उपयोग करने के लिए इसे उसी अंदाज में काटें जो आपको उम्मीद है। लेकिन इससे कोई फर्क नहीं पड़ता:>>> round(0.1, 1) 0.10000000000000001
समस्या यह है कि बाइनरी फ्लोटिंग-पॉइंट मूल्य के लिए संग्रहीत
“0.1”
पहले से ही सबसे अच्छा संभव बाइनरी सन्निकटन था1/10
, इसलिए इसे फिर से गोल करने की कोशिश करना बेहतर नहीं बना सकता है: यह पहले से ही उतना ही अच्छा था जितना कि यह हो जाता है।एक और परिणाम यह है कि चूंकि
0.1
बिल्कुल नहीं है1/10
, दस मानों को0.1
सम्मिलित करें1.0
, बिलकुल नहीं।>>> sum = 0.0 >>> for i in range(10): ... sum += 0.1 ... >>> sum 0.99999999999999989
आपकी समस्याओं का एक वैकल्पिक और समाधान decimal
मॉड्यूल का उपयोग करना होगा ।
जैसा कि @Matt ने बताया, पायथन 3.6 एफ-स्ट्रिंग्स प्रदान करता है , और वे नेस्टेड मापदंडों का भी उपयोग कर सकते हैं :
value = 2.34558
precision = 2
width = 4
print(f'result: {value:{width}.{precision}f}')
जो प्रदर्शित करेगा result: 2.35
यह वही कर रहा है जो आपने इसे करने के लिए कहा था और सही तरीके से काम कर रहा है। फ़्लोटिंग पॉइंट भ्रम के बारे में और पढ़ें और शायद इसके बजाय दशमलव ऑब्जेक्ट आज़माएं ।
दशमलव वस्तु और गोल () विधि के संयोजन का उपयोग करें।
Python 3.7.3
>>> from decimal import Decimal
>>> d1 = Decimal (13.949999999999999) # define a Decimal
>>> d1
Decimal('13.949999999999999289457264239899814128875732421875')
>>> d2 = round(d1, 2) # round to 2 decimals
>>> d2
Decimal('13.95')
पायथन और जावास्क्रिप्ट जैसी टाइप-डायनेमिक भाषाओं में फ़्लोटिंग पॉइंट को ठीक करने के लिए, मैं इस तकनीक का उपयोग करता हूं
# For example:
a = 70000
b = 0.14
c = a * b
print c # Prints 980.0000000002
# Try to fix
c = int(c * 10000)/100000
print c # Prints 980
आप निम्न के रूप में दशमलव का उपयोग भी कर सकते हैं:
from decimal import *
getcontext().prec = 6
Decimal(1) / Decimal(7)
# Results in 6 precision -> Decimal('0.142857')
getcontext().prec = 28
Decimal(1) / Decimal(7)
# Results in 28 precision -> Decimal('0.1428571428571428571428571429')
getcontext().prec = 6
केवल कार्यक्षेत्र या सभी स्थानों के लिए काम करता है?
from decimal import Decimal
def round_float(v, ndigits=2, rt_str=False):
d = Decimal(v)
v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits))
if rt_str:
return v_str
return Decimal(v_str)
परिणाम:
Python 3.6.1 (default, Dec 11 2018, 17:41:10)
>>> round_float(3.1415926)
Decimal('3.14')
>>> round_float(3.1445926)
Decimal('3.14')
>>> round_float(3.1455926)
Decimal('3.15')
>>> round_float(3.1455926, rt_str=True)
'3.15'
>>> str(round_float(3.1455926))
'3.15'
इस तरह के एक लंबो कार्य के बारे में क्या:
arred = lambda x,n : x*(10**n)//1/(10**n)
इस तरह आप बस कर सकते हैं:
arred(3.141591657,2)
और पाओ
3.14
यह 1,2,3 की तरह सरल है:
दशमलव का उपयोग करेंतेजी से सही ढंग से गोल दशमलव अस्थायी बिंदु अंकगणित के लिए मॉड्यूल का :
d = दशमलव (10000000.0000009)
गोलाई प्राप्त करने के लिए:
d.quantize(Decimal('0.01'))
के साथ परिणाम होगा Decimal('10000000.00')
def round_decimal(number, exponent='0.01'):
decimal_value = Decimal(number)
return decimal_value.quantize(Decimal(exponent))
या
def round_decimal(number, decimal_places=2):
decimal_value = Decimal(number)
return decimal_value.quantize(Decimal(10) ** -decimal_places)
पुनश्च: दूसरों की आलोचना: स्वरूपण गोल नहीं है।
किसी संख्या को किसी रिज़ॉल्यूशन में राउंड करने के लिए, सबसे अच्छा तरीका निम्नलिखित है, जो किसी भी रिज़ॉल्यूशन के साथ काम कर सकता है (0.01 दो दशमलव या अन्य चरणों के लिए):
>>> import numpy as np
>>> value = 13.949999999999999
>>> resolution = 0.01
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
13.95
>>> resolution = 0.5
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
14.0
numpy.round
सटीकता / सटीकता से आती है । इसलिए इसे रिज़ॉल्यूशन के साथ गुणा करने से पहले इसे परिभाषित करना होगा। मैंने कोड अपडेट किया। उसके लिये आपका धन्यवाद!
numpy.float64
np.round के परिणाम को float
या केवल उपयोग करने के लिए परिवर्तित करना round(value, 2)
। कोई वैध IEEE 754 नंबर 13.949999999999999 (= 1395 / 100.) और 3.950000000000001 (= 1395 * .01) के बीच मौजूद है। आपको क्यों लगता है कि आपका तरीका सबसे अच्छा है? मूल मूल्य 13.949999999999999289 (= मान = दौर (मान, 2)) आपके 13.95000000000000178 (np.float96 द्वारा मुद्रित) से भी अधिक सटीक है। सुन्न के लिए भी अधिक जानकारी अब मेरे जवाब में जोड़ दी गई है कि आप शायद गलती से नीचे गए हैं। यह मूल रूप से सुन्न के बारे में नहीं था।
int
भी उपयोग कर सकते हैं float
। आपकी अतिरिक्त टिप्पणी के लिए धन्यवाद। (क्षमा करें, लेकिन मैंने आपको
मेरे द्वारा उपयोग की जाने वाली विधि स्ट्रिंग स्लाइसिंग है। यह अपेक्षाकृत जल्दी और सरल है।
सबसे पहले, फ्लोट को एक स्ट्रिंग में परिवर्तित करें, जिस लंबाई को आप चाहते हैं उसे चुनें।
float = str(float)[:5]
ऊपर एकल पंक्ति में, हमने मान को एक स्ट्रिंग में बदल दिया है, फिर स्ट्रिंग को केवल अपने पहले चार अंकों या वर्णों (समावेशी) में रखा है।
उम्मीद है की वो मदद करदे!