पायथन में महत्वपूर्ण आंकड़ों के लिए एक संख्या को गोल कैसे करें


148

मुझे UI में प्रदर्शित होने के लिए फ़्लोट को राउंड करना होगा। जैसे, एक महत्वपूर्ण आंकड़ा:

1234 -> 1000

0.12 -> 0.1

0.012 -> 0.01

0.062 -> 0.06

6253 -> 6000

1999 -> 2000

क्या पायथन लाइब्रेरी का उपयोग करने का एक अच्छा तरीका है, या क्या मुझे इसे स्वयं लिखना है?


2
क्या आप केवल आउटपुट स्वरूपण कर रहे हैं? क्या आप इस बारे में पूछ रहे हैं? docs.python.org/library/stdtypes.html#string-formatting या यह? docs.python.org/library/string.html#string-formatting
S.Lott

क्या आउटपुट आप 0.062 और 6253 के लिए उम्मीद करते हैं?
लमिरप

पैकेज टू-प्रिसिजन अब ऐसा करता है। मेरा पोस्ट किया गया उत्तर विवरण यह कैसे लागू होता है।
विलियम रुस्नाक

जवाबों:


146

पूर्णांक को राउंड करने के लिए आप ऋणात्मक संख्याओं का उपयोग कर सकते हैं:

>>> round(1234, -3)
1000.0

इस प्रकार यदि आपको केवल सबसे महत्वपूर्ण अंक चाहिए:

>>> from math import log10, floor
>>> def round_to_1(x):
...   return round(x, -int(floor(log10(abs(x)))))
... 
>>> round_to_1(0.0232)
0.02
>>> round_to_1(1234243)
1000000.0
>>> round_to_1(13)
10.0
>>> round_to_1(4)
4.0
>>> round_to_1(19)
20.0

अगर आप 1 से बड़े हैं तो आपको फ्लोट को पूर्णांक में बदलने का ध्यान रखना होगा।


3
यह सही उपाय है। का उपयोग करते हुए log10यह दौर के लिए कैसे निर्धारित करने के लिए केवल उचित तरीका है।
वोल्फ

73
round_to_n = lambda x, n: राउंड (x, -int (फ्लोर (log10 (x))) + (n - 1))
रॉय ह्यूनजिन हन

28
आपको उपयोग करना चाहिए log10(abs(x)), अन्यथा नकारात्मक संख्या विफल हो जाएगी (और x == 0निश्चित रूप से अलग से इलाज करें )
टोबियास किन्ज़लर

2
मैंने एक पैकेज बनाया है जो अब ऐसा करता है और शायद इस से अधिक आसान और अधिक मजबूत है। पोस्ट लिंक , रेपो लिंक । उम्मीद है की यह मदद करेगा!
विलियम रुस्नाक

2
round_to_n = lambda x, n: x if x == 0 else round(x, -int(math.floor(math.log10(abs(x)))) + (n - 1))के खिलाफ की रक्षा करता है x==0और x<0धन्यवाद @RoyHyunjinHan और @TobiasKienzler। गणित की तरह अपरिभाषित के खिलाफ संरक्षित नहीं है, या कचरा नहीं जैसे कोई भी आदि
AJP

98

स्ट्रिंग फॉर्मेटिंग में% g कुछ महत्वपूर्ण आंकड़ों के लिए एक फ्लोट राउंड को प्रारूपित करेगा। यह कभी-कभी 'ई' वैज्ञानिक संकेतन का उपयोग करेगा, इसलिए गोल स्ट्रिंग को फ़्लोट में फिर% s स्ट्रिंग स्वरूपण के माध्यम से परिवर्तित करें।

>>> '%s' % float('%.1g' % 1234)
'1000'
>>> '%s' % float('%.1g' % 0.12)
'0.1'
>>> '%s' % float('%.1g' % 0.012)
'0.01'
>>> '%s' % float('%.1g' % 0.062)
'0.06'
>>> '%s' % float('%.1g' % 6253)
'6000.0'
>>> '%s' % float('%.1g' % 1999)
'2000.0'

7
ओपी की आवश्यकता 1999 के लिए '2000' के रूप में प्रारूपित करने के लिए थी, न कि '2000.0' के रूप में। मैं इसे प्राप्त करने के लिए अपने तरीके को बदलने के लिए एक तुच्छ तरीका नहीं देख सकता।
टिम मार्टिन

1
यह वही है जो मैं हमेशा चाहता था! आपको यह कहां मिलेगा?
djhaskin987

12
ध्यान दें कि% g का व्यवहार हमेशा सही नहीं होता है। विशेष रूप से यह हमेशा शून्य को पीछे छोड़ता है, भले ही वे महत्वपूर्ण हों। संख्या 1.23400 में 6 महत्वपूर्ण अंक हैं, लेकिन "% .6g"% (1.23400) के परिणामस्वरूप "1.234" होगा जो गलत है। इस ब्लॉग पोस्ट में अधिक जानकारी: randlet.com/blog/python-significant-figures-format
randlet

3
एवगेनी के जवाब में विधि की तरह, यह सही ढंग से गोल 0.075करने में विफल रहता है 0.08। इसके 0.07बदले लौटता है ।
गेब्रियल

1
round_sig = lambda f,p: float(('%.' + str(p) + 'e') % f)आपको महत्वपूर्ण अंकों की संख्या को समायोजित करने की अनुमति देता है!
डेनिजब

49

यदि आप 1 से अधिक महत्वपूर्ण दशमलव रखना चाहते हैं (अन्यथा इवगेनी के समान ही):

>>> from math import log10, floor
>>> def round_sig(x, sig=2):
...   return round(x, sig-int(floor(log10(abs(x))))-1)
... 
>>> round_sig(0.0232)
0.023
>>> round_sig(0.0232, 1)
0.02
>>> round_sig(1234243, 3)
1230000.0

8
round_sig (-0.0232) -> गणित डोमेन त्रुटि, आप वहां एक abs () जोड़ना चाहते हैं;)
dgorissen

2
एवगेनी और पीटर ग्राहम के जवाबों के तरीकों की तरह, यह सही तरीके से गोल नहीं 0.075हो पाता है 0.08। इसके 0.07बदले लौटता है ।
गेब्रियल

3
इसके अलावा यह round_sig (0) के लिए विफल रहता है।
युवल एट्ज़मन

2
@ गैब्रिएल जो आपके कंप्यूटर पर चल रहे अजगर की "सुविधा" में बनाया गया है, और फ़ंक्शन के अपने व्यवहार में खुद को प्रकट करता है rounddocs.python.org/2/tutorial/floatingpoint.html#tut-fp-issues
C

1
@ गैब्रिएल मैंने एक जवाब जोड़ा है जो बताता है कि आपको "0.075" राउंड से 0.7 वापस पाने की उम्मीद क्यों करनी चाहिए ! देखें stackoverflow.com/a/56974893/1358308
सैम मेसन

30
f'{float(f"{i:.1g}"):g}'
# Or with Python <3.6,
'{:g}'.format(float('{:.1g}'.format(i)))

यह समाधान अन्य सभी से अलग है क्योंकि:

  1. यह बिल्कुल ओपी प्रश्न को हल करता है
  2. इसे किसी अतिरिक्त पैकेज की आवश्यकता नहीं है
  3. यह करता है नहीं किसी भी उपयोगकर्ता परिभाषित जरूरत सहायक समारोह या गणितीय प्रक्रिया

nमहत्वपूर्ण आंकड़ों की एक मनमानी संख्या के लिए, आप उपयोग कर सकते हैं:

print('{:g}'.format(float('{:.{p}g}'.format(i, p=n))))

परीक्षा:

a = [1234, 0.12, 0.012, 0.062, 6253, 1999, -3.14, 0., -48.01, 0.75]
b = ['{:g}'.format(float('{:.1g}'.format(i))) for i in a]
# b == ['1000', '0.1', '0.01', '0.06', '6000', '2000', '-3', '0', '-50', '0.8']

नोट : इस समाधान के साथ, इनपुट से गतिशील रूप से महत्वपूर्ण आंकड़ों की संख्या को अनुकूलित करना संभव नहीं है क्योंकि संख्याओं को अलग करने वाले शून्य ( 3.14 == 3.1400) के साथ संख्याओं को अलग करने का कोई मानक तरीका नहीं है । यदि आपको ऐसा करने की आवश्यकता है, तो इन -प्रिसिजन पैकेज में दिए गए गैर-मानक कार्यों की आवश्यकता है।


FYI करें: मुझे यह समाधान स्वतंत्र रूप से eddygeek से मिला जब मैं अपने कोड में एक ही समस्या को हल करने की कोशिश कर रहा था। अब मुझे एहसास हुआ कि मेरा समाधान, जाहिर है, लगभग उसी के समान है (मैंने सिर्फ गलत आउटपुट पर ध्यान दिया और कोड, मेरी गलती को पढ़ने के लिए परेशान नहीं किया)। संभवतः उनके उत्तर के नीचे एक छोटी टिप्पणी एक नए उत्तर के बजाय पर्याप्त होती ... केवल (कुंजी) अंतर फॉर्मैटर का दोहरा उपयोग है :gजो पूर्णांक को संरक्षित करता है।
फाल्कन

वाह, आपके जवाब को वास्तव में ऊपर से नीचे तक पढ़ने की जरूरत है;) यह डबल-कास्ट ट्रिक गंदा है, लेकिन साफ ​​है। (ध्यान दें कि १ ९९९ के रूप में स्वरूपित ५ महत्वपूर्ण अंकों का 2000.0 पता चलता है , इसलिए इसे {:g}फिर से गुजरना पड़ता है।) सामान्य तौर पर, अनुगामी शून्य के साथ पूर्णांक महत्वपूर्ण आंकड़ों के संबंध में अस्पष्ट होते हैं, जब तक कि कुछ तकनीक (जैसे पिछले महत्वपूर्ण से ऊपर की ओर) का उपयोग नहीं किया जाता है।
टॉमस गैंडर

8

मैंने पैकेज को सटीक बनाया है जो आपको चाहिए। यह आपको अपने नंबरों को अधिक या कम महत्वपूर्ण आंकड़े देने की अनुमति देता है।

यह एक महत्वपूर्ण संख्या के साथ मानक, वैज्ञानिक और इंजीनियरिंग नोटेशन को भी आउटपुट करता है।

स्वीकृत उत्तर में रेखा है

>>> round_to_1(1234243)
1000000.0

यह वास्तव में 8 सिग अंजीर को निर्दिष्ट करता है। संख्या 1234243 के लिए मेरी लाइब्रेरी केवल एक महत्वपूर्ण आंकड़ा प्रदर्शित करती है:

>>> from to_precision import to_precision
>>> to_precision(1234243, 1, 'std')
'1000000'
>>> to_precision(1234243, 1, 'sci')
'1e6'
>>> to_precision(1234243, 1, 'eng')
'1e6'

यह अंतिम महत्वपूर्ण आकृति को भी गोल करेगा और स्वचालित रूप से यह चुन सकता है कि यदि नोटेशन निर्दिष्ट नहीं है तो क्या उपयोग करना है:

>>> to_precision(599, 2)
'600'
>>> to_precision(1164, 2)
'1.2e3'

अब मैं उसी की तलाश कर रहा हूं लेकिन
mhoff

@ म्हॉफ आप शायद लंबोदर के साथ पंडों के नक्शे का उपयोग कर सकते हैं। lambda x: to_precision(x, 2)
विलियम रुस्नाक

इसे (PyPI) [ pypi.org/] में जोड़ें । ऐसा कुछ भी नहीं है जो वहां मौजूद है, जहां तक ​​मैं बता सकता हूं।
मोर्गोथ

यह एक शानदार पैकेज है, लेकिन मुझे लगता है कि अधिकांश सुविधाएँ अब सिगफिग मॉड्यूल में हैं
हाइपरएक्टिव एनवी

1
इसका एक बग है: std_notation (9.999999999999999e-05, 3) देता है: '0.00010' जो केवल 2 महत्वपूर्ण अंक है
बोरिस मुलर

5

पूर्णांक को 1 महत्वपूर्ण आकृति में गोल करने के लिए मूल विचार यह है कि बिंदु और गोल से पहले इसे 1 अंक के साथ एक अस्थायी बिंदु में परिवर्तित किया जाए, फिर इसे अपने मूल पूर्णांक आकार में परिवर्तित करें।

ऐसा करने के लिए हमें पूर्णांक से कम 10 की सबसे बड़ी शक्ति को जानना होगा। हम इसके लिए लॉग 10 फ़ंक्शन के फर्श का उपयोग कर सकते हैं।

from math import log10, floor
def round_int(i,places):
    if i == 0:
        return 0
    isign = i/abs(i)
    i = abs(i)
    if i < 1:
        return 0
    max10exp = floor(log10(i))
    if max10exp+1 < places:
        return i
    sig10pow = 10**(max10exp-places+1)
    floated = i*1.0/sig10pow
    defloated = round(floated)*sig10pow
    return int(defloated*isign)

1
प्लस एक समाधान के लिए जो अजगर के दौर (.., अंक) के बिना काम करता है और कोई तार संलग्न नहीं है!
स्टीव रोजर्स

5

सीधे सवाल का जवाब देने के लिए, यहां आर फ़ंक्शन से नामकरण का उपयोग करके मेरा संस्करण है :

import math

def signif(x, digits=6):
    if x == 0 or not math.isfinite(x):
        return x
    digits -= math.ceil(math.log10(abs(x)))
    return round(x, digits)

इस उत्तर को पोस्ट करने का मेरा मुख्य कारण शिकायत करने वाली टिप्पणियां हैं जो "0.075" राउंड 0.08 के बजाय 0.07 हैं। यह कारण है, जैसा कि "नोविस सी" द्वारा इंगित किया गया है, फ्लोटिंग पॉइंट अंकगणित के संयोजन के लिए दोनों परिमित परिशुद्धता और बेस -2 प्रतिनिधित्व है । निकटतम संख्या 0.075 जिसे वास्तव में दर्शाया जा सकता है, थोड़ा छोटा है, इसलिए आपके द्वारा भोलेपन की अपेक्षा से गोलाई अलग तरह से निकलती है।

यह भी ध्यान दें कि यह गैर-दशमलव फ़्लोटिंग पॉइंट अंकगणित के किसी भी उपयोग पर लागू होता है, जैसे सी और जावा दोनों में एक ही मुद्दा है।

अधिक विस्तार से दिखाने के लिए, हम पायथन को "हेक्स" प्रारूप में संख्या को प्रारूपित करने के लिए कहते हैं:

0.075.hex()

जो हमें देता है 0x1.3333333333333p-4:। ऐसा करने का कारण यह है कि सामान्य दशमलव प्रतिनिधित्व में अक्सर गोलाई शामिल होती है और इसलिए यह नहीं है कि कंप्यूटर वास्तव में संख्या को "कैसे" देखता है। यदि आप इस प्रारूप में उपयोग नहीं किए जाते हैं, तो कुछ उपयोगी संदर्भ पायथन डॉक्स और सी मानक हैं

यह दिखाने के लिए कि ये संख्याएँ किस तरह से काम करती हैं, हम अपने शुरुआती बिंदु पर वापस आ सकते हैं:

0x13333333333333 / 16**13 * 2**-4

जिसे छापना चाहिए 0.07516**13दशमलव बिंदु के बाद 13 हेक्साडेसिमल अंक हैं, और 2**-4हेक्स घातांक बेस -2 हैं क्योंकि इसलिए है।

अब हमारे पास कुछ विचार है कि कैसे झंडे का प्रतिनिधित्व किया जाता है हम इसका उपयोग कर सकते हैं decimal मॉड्यूल का हमें कुछ और सटीक दे , हमें दिखा सकते हैं कि क्या चल रहा है:

from decimal import Decimal

Decimal(0x13333333333333) / 16**13 / 2**4

दे रहा है: 0.07499999999999999722444243844और उम्मीद है कि क्यों round(0.075, 2)मूल्यांकन करने के लिए समझा रहा है0.07


1
यह इस बात का एक बड़ा विवरण है कि क्यों 0.075 को कोड स्तर पर 0.07 तक राउंड किया गया है , लेकिन हमें (भौतिक विज्ञान में) हमेशा राउंड अप नहीं करने के लिए सिखाया गया है। इसलिए अपेक्षित व्यवहार वास्तव में 0.08 के परिणामस्वरूप, फ्लोटिंग पॉइंट सटीक मुद्दों के बावजूद है।
गेब्रियल

1
मैं अनिश्चित हूं कि आपका भ्रम कहां है: जब आप 0.075 दर्ज करते हैं तो आप वास्तव में ~ 0.07499 (ऊपर) दर्ज कर रहे हैं, जो सामान्य गणित के नियमों के अनुसार गोल होता है। यदि आप एक डेटा प्रकार (जैसे दशमलव फ़्लोटिंग पॉइंट ) का उपयोग कर रहे थे जो 0.075 का प्रतिनिधित्व कर सकता है, तो यह वास्तव में 0.08 के लिए गोल होना चाहिए
सैम मेसन

मैं भ्रमित नहीं हूँ। जब मैं 0.075 में प्रवेश करता हूं तो मैं वास्तव में 0.075 में प्रवेश कर रहा हूं। कोड के अंदर फ्लोटिंग पॉइंट गणित में जो कुछ भी होता है, मुझे परवाह नहीं है।
गेब्रियल

@Gabriel: और अगर आप था जानबूझ में प्रवेश किया 0.074999999999999999, क्या आपको लगता है कि इस मामले में प्राप्त करने की उम्मीद करेंगे?
मार्क डिकिंसन

@MarkDickinson निर्भर करता है। एक महत्वपूर्ण आंकड़ा: 0.07, दो: 0.075।
गेब्रियल

4
def round_to_n(x, n):
    if not x: return 0
    power = -int(math.floor(math.log10(abs(x)))) + (n - 1)
    factor = (10 ** power)
    return round(x * factor) / factor

round_to_n(0.075, 1)      # 0.08
round_to_n(0, 1)          # 0
round_to_n(-1e15 - 1, 16) # 1000000000000001.0

उम्मीद है कि ऊपर दिए गए सभी उत्तरों में से सबसे अच्छा लेते हुए (एक पंक्ति में लंबोदर के रूप में इसे डालने में सक्षम होने के कारण;))। अभी तक खोज नहीं की गई है, इस उत्तर को संपादित करने के लिए स्वतंत्र महसूस करें:

round_to_n(1e15 + 1, 11)  # 999999999999999.9

4

मैंने ऋणात्मक संख्याओं और छोटी संख्या (शून्य सहित) को संभालने के लिए इंदर के समाधान को संशोधित किया।

from math import log10, floor
def round_sig(x, sig=6, small_value=1.0e-9):
    return round(x, sig - int(floor(log10(max(abs(x), abs(small_value))))) - 1)

सिर्फ टेस्ट ही क्यों x == 0? यदि आप एक-लाइनर से प्यार करते हैं, तो बस return 0 if x==0 else round(...)
pjvandehaar

2
@pjvandehaar, आप सामान्य मामले के लिए सही हैं और मुझे इसे लागू करना चाहिए। इसके अलावा, संख्यात्मक गणनाओं के लिए मुझे प्रदर्शन करने की आवश्यकता है ताकि हमें कभी-कभी 1e-15 जैसी संख्या मिल सके। हमारे आवेदन में हम दो छोटे संख्याओं की तुलना करना चाहते हैं (जिनमें से एक शून्य हो सकता है) को समान माना जाता है। इसके अलावा कुछ लोग छोटी संख्याओं को गोल करना चाहते हैं (यह 1e-9, 1e-15 या 1e-300 भी हो सकता है)।
ryan281

1
दिलचस्प। यह समझाने के लिए धन्यवाद। उस मामले में, मैं वास्तव में इस समाधान को पसंद करता हूं।
पंजवन्धर

@ मॉर्गोथ यह एक दिलचस्प और कठिन समस्या है। जैसा कि आपने बताया, मुद्रित मूल्य 3 महत्वपूर्ण अंक नहीं दिखाता है, लेकिन मूल्य सही है (जैसे 0.970 == 0.97)। मुझे लगता है कि आप कुछ अन्य प्रिंट समाधानों का उपयोग कर सकते हैं जैसे f'{round_sig(0.9701, sig=3):0.3f}'कि आप शून्य मुद्रित करना चाहते हैं।
ryan281

3

यदि आप तार को शामिल किए बिना गोल करना चाहते हैं, तो मैंने जो लिंक पाया है वह उपरोक्त टिप्पणियों में दफन है:

http://code.activestate.com/lists/python-tutor/70739/

मुझे सबसे अच्छा लगता है। फिर जब आप किसी भी स्ट्रिंग फॉर्मेटिंग डिस्क्रिप्टर के साथ प्रिंट करते हैं, तो आपको एक उचित आउटपुट मिलता है, और आप अन्य गणना उद्देश्यों के लिए संख्यात्मक प्रतिनिधित्व का उपयोग कर सकते हैं।

लिंक पर कोड एक तीन लाइनर है: डीईएफ, डॉक्टर, और वापसी। इसमें एक बग है: आपको लॉगरिदम विस्फोट करने की जांच करने की आवश्यकता है। वह आसान है। से इनपुट की तुलना करें sys.float_info.min। पूर्ण समाधान है:

import sys,math

def tidy(x, n):
"""Return 'x' rounded to 'n' significant digits."""
y=abs(x)
if y <= sys.float_info.min: return 0.0
return round( x, int( n-math.ceil(math.log10(y)) ) )

यह किसी भी स्केलर संख्यात्मक मान के लिए काम करता है, और n हो सकता है floatयदि आपको किसी कारण से प्रतिक्रिया को स्थानांतरित करने की आवश्यकता हो। आप वास्तव में सीमा को आगे बढ़ा सकते हैं:

sys.float_info.min*sys.float_info.epsilon

बिना किसी त्रुटि के, यदि किसी कारण से आप न्यूनतम मान के साथ काम कर रहे हैं।


2

मैं ऐसी किसी भी चीज़ के बारे में नहीं सोच सकता जो इस बॉक्स से बाहर हो सकेगी। लेकिन यह फ्लोटिंग पॉइंट नंबरों के लिए काफी अच्छी तरह से संभाला जाता है।

>>> round(1.2322, 2)
1.23

घुसपैठिए चालबाज हैं। उन्हें स्मृति में आधार 10 के रूप में संग्रहीत नहीं किया जाता है, इसलिए महत्वपूर्ण स्थान ऐसा करना स्वाभाविक बात नहीं है। हालांकि यह एक स्ट्रिंग है, हालांकि इसे लागू करना काफी तुच्छ है।

या पूर्णांकों के लिए:

>>> def intround(n, sigfigs):
...   n = str(n)
...   return n[:sigfigs] + ('0' * (len(n)-(sigfigs)))

>>> intround(1234, 1)
'1000'
>>> intround(1234, 2)

यदि आप एक फ़ंक्शन बनाना चाहते हैं जो किसी भी संख्या को संभालता है, तो मेरी प्राथमिकता उन दोनों को स्ट्रिंग में बदलना और एक दशमलव स्थान की तलाश करना है जो यह तय करेगा कि क्या करना है:

>>> def roundall1(n, sigfigs):
...   n = str(n)
...   try:
...     sigfigs = n.index('.')
...   except ValueError:
...     pass
...   return intround(n, sigfigs)

एक अन्य विकल्प प्रकार के लिए जाँच करना है। यह बहुत कम लचीला होगा, और संभवतः अन्य संख्याओं जैसे Decimalवस्तुओं के साथ अच्छी तरह से नहीं खेलेंगे :

>>> def roundall2(n, sigfigs):
...   if type(n) is int: return intround(n, sigfigs)
...   else: return round(n, sigfigs)

बस तारों के साथ खिलवाड़ करना संख्याओं को गोल नहीं करेगा। 1999 का 1 महत्वपूर्ण आंकड़ा 2000 है, 1000 का नहीं।
पीटर ग्राहम


2

पोस्ट किए गए उत्तर को दिए जाने पर सबसे अच्छा उपलब्ध था, लेकिन इसकी कई सीमाएं हैं और तकनीकी रूप से महत्वपूर्ण आंकड़ों को सही नहीं करता है।

numpy.format_float_positional सीधे इच्छित व्यवहार का समर्थन करता है। निम्न टुकड़ा xवैज्ञानिक संकेतन दबा के साथ 4 महत्वपूर्ण आंकड़ों के लिए स्वरूपित फ्लोट देता है ।

import numpy as np
x=12345.6
np.format_float_positional(x, precision=4, unique=False, fractional=False, trim='k')
> 12340.

प्रलेखन ( numpy.org/doc/stable/reference/generated/… पर ले जाया गया ) बताता है कि यह फ़ंक्शन ड्रैगन 4 एल्गोरिथ्म (स्टील एंड व्हाइट 1990, dl.acm.org/doi/pdf.1145/93542.93559 ) को लागू करता है। यह कष्टप्रद परिणाम पैदा करता है, जैसे print(*[''.join([np.format_float_positional(.01*a*n,precision=2,unique=False,fractional=False,trim='k',pad_right=5) for a in [.99, .999, 1.001]]) for n in [8,9,10,11,12,19,20,21]],sep='\n')। मैं खुद ड्रैगन 4 की जाँच नहीं करता था।
रेनल्ड62

0

मैं इसमें भी भाग गया लेकिन मुझे गोलाई के प्रकार पर नियंत्रण की आवश्यकता थी। इस प्रकार, मैंने एक त्वरित फ़ंक्शन (नीचे कोड देखें) लिखा है जो मूल्य, गोल प्रकार, और वांछित महत्वपूर्ण अंकों को ध्यान में रख सकता है।

import decimal
from math import log10, floor

def myrounding(value , roundstyle='ROUND_HALF_UP',sig = 3):
    roundstyles = [ 'ROUND_05UP','ROUND_DOWN','ROUND_HALF_DOWN','ROUND_HALF_UP','ROUND_CEILING','ROUND_FLOOR','ROUND_HALF_EVEN','ROUND_UP']

    power =  -1 * floor(log10(abs(value)))
    value = '{0:f}'.format(value) #format value to string to prevent float conversion issues
    divided = Decimal(value) * (Decimal('10.0')**power) 
    roundto = Decimal('10.0')**(-sig+1)
    if roundstyle not in roundstyles:
        print('roundstyle must be in list:', roundstyles) ## Could thrown an exception here if you want.
    return_val = decimal.Decimal(divided).quantize(roundto,rounding=roundstyle)*(decimal.Decimal(10.0)**-power)
    nozero = ('{0:f}'.format(return_val)).rstrip('0').rstrip('.') # strips out trailing 0 and .
    return decimal.Decimal(nozero)


for x in list(map(float, '-1.234 1.2345 0.03 -90.25 90.34543 9123.3 111'.split())):
    print (x, 'rounded UP: ',myrounding(x,'ROUND_UP',3))
    print (x, 'rounded normal: ',myrounding(x,sig=3))

0

अजगर 2.6+ नए-शैली प्रारूपण का उपयोग करना (जैसा कि% -स्टाइल को पदावनत किया गया है))

>>> "{0}".format(float("{0:.1g}".format(1216)))
'1000.0'
>>> "{0}".format(float("{0:.1g}".format(0.00356)))
'0.004'

अजगर 2.7+ में आप अग्रणी 0s को छोड़ सकते हैं ।


अजगर के किस संस्करण के साथ? पायथन 3.6.3 | एनाकोंडा, इंक (डिफ़ॉल्ट, 13 अक्टूबर 2017, 12:02:49) वही पुरानी गोलाई समस्या है। "{0}"। प्रारूप (फ्लोट ("{0: .1g}"। प्रारूप (0.075)) '0.07' पैदावार, '0.08' नहीं
डॉन Mclachlan

@DonMclachlan मैं क्यों इस में आशा की जाती है की एक विवरण जोड़ दिया है stackoverflow.com/a/56974893/1358308
सैम मेसन

0

यह फ़ंक्शन एक सामान्य दौर करता है यदि संख्या 10 ** (- दशमलव_पोसिशन) से बड़ी है, अन्यथा सार्थक दशमलव पदों की संख्या तक पहुंचने तक अधिक दशमलव जोड़ता है:

def smart_round(x, decimal_positions):
    dp = - int(math.log10(abs(x))) if x != 0.0 else int(0)
    return round(float(x), decimal_positions + dp if dp > 0 else decimal_positions)

आशा करता हूँ की ये काम करेगा।


0

https://stackoverflow.com/users/1391441/gabriel , rnd (.075, 1) के बारे में आपकी चिंता का विषय है? कैविएट: फ्लोट के रूप में मान लौटाता है

def round_to_n(x, n):
    fmt = '{:1.' + str(n) + 'e}'    # gives 1.n figures
    p = fmt.format(x).split('e')    # get mantissa and exponent
                                    # round "extra" figure off mantissa
    p[0] = str(round(float(p[0]) * 10**(n-1)) / 10**(n-1))
    return float(p[0] + 'e' + p[1]) # convert str to float

>>> round_to_n(750, 2)
750.0
>>> round_to_n(750, 1)
800.0
>>> round_to_n(.0750, 2)
0.075
>>> round_to_n(.0750, 1)
0.08
>>> math.pi
3.141592653589793
>>> round_to_n(math.pi, 7)
3.141593

0

यह एक स्ट्रिंग लौटाता है, जिससे कि आंशिक भागों के बिना परिणाम होता है, और छोटे मान जो अन्यथा ई नोटेशन में दिखाई देंगे, सही तरीके से दिखाए गए हैं:

def sigfig(x, num_sigfig):
    num_decplace = num_sigfig - int(math.floor(math.log10(abs(x)))) - 1
    return '%.*f' % (num_decplace, round(x, num_decplace))

0

एक प्रश्न को देखते हुए इतनी अच्छी तरह से उत्तर दिया गया कि दूसरे को क्यों नहीं जोड़ा जाए

यह मेरी सुंदरता को थोड़ा बेहतर बनाता है, हालांकि उपरोक्त में से कई तुलनीय हैं

import numpy as np

number=-456.789
significantFigures=4

roundingFactor=significantFigures - int(np.floor(np.log10(np.abs(number)))) - 1
rounded=np.round(number, roundingFactor)

string=rounded.astype(str)

print(string)

यह अलग-अलग संख्याओं और संख्यात्मक सरणियों के लिए काम करता है, और नकारात्मक संख्याओं के लिए ठीक काम करना चाहिए।

एक अतिरिक्त कदम है जिसे हम जोड़ सकते हैं - np.round () एक दशमलव संख्या देता है, भले ही गोल एक पूर्णांक हो (यानी महत्वपूर्णफिगर = 2 के लिए हम -460 वापस पाने की उम्मीद कर सकते हैं, लेकिन इसके बजाय हमें -460.0 मिलता है)। हम इस कदम को उसके लिए सही करने के लिए जोड़ सकते हैं:

if roundingFactor<=0:
    rounded=rounded.astype(int)

दुर्भाग्य से, यह अंतिम चरण संख्याओं की एक सरणी के लिए काम नहीं करेगा - मैं आपको प्रिय पाठक को छोड़ दूंगा ताकि आपको ज़रूरत हो।



0
import math

  def sig_dig(x, n_sig_dig):
      num_of_digits = len(str(x).replace(".", ""))
      if n_sig_dig >= num_of_digits:
          return x
      n = math.floor(math.log10(x) + 1 - n_sig_dig)
      result = round(10 ** -n * x) * 10 ** n
      return float(str(result)[: n_sig_dig + 1])


    >>> sig_dig(1234243, 3)
    >>> sig_dig(243.3576, 5)

        1230.0
        243.36
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.