पाइथन में तैरती ट्रंकटिंग


110

मैं एक फ्लोट से अंकों को डॉट के बाद निश्चित अंकों की संख्या निकालना चाहता हूं, जैसे:

1.923328437452 -> 1.923

मुझे दूसरे फ़ंक्शन के लिए एक स्ट्रिंग के रूप में आउटपुट करने की आवश्यकता है, प्रिंट नहीं।

इसके अलावा, मैं खोए हुए अंकों को अनदेखा करना चाहता हूं, न कि उन्हें गोल करना।


4
क्या -1.233 को -1.23 या -1.24 से कम किया जाना चाहिए?
एंटनी हैचकिंस

जवाबों:


116

पहला, फ़ंक्शन, उन लोगों के लिए जो सिर्फ कुछ कॉपी-एंड-पेस्ट कोड चाहते हैं:

def truncate(f, n):
    '''Truncates/pads a float f to n decimal places without rounding'''
    s = '{}'.format(f)
    if 'e' in s or 'E' in s:
        return '{0:.{1}f}'.format(f, n)
    i, p, d = s.partition('.')
    return '.'.join([i, (d+'0'*n)[:n]])

यह पायथन 2.7 और 3.1+ में मान्य है। पुराने संस्करणों के लिए, एक ही "बुद्धिमान गोलाई" प्रभाव प्राप्त करना संभव नहीं है (कम से कम, बहुत सारे जटिल कोड के बिना नहीं), लेकिन छंटनी से पहले 12 दशमलव स्थानों पर चक्कर लगाना अधिक समय तक काम करेगा:

def truncate(f, n):
    '''Truncates/pads a float f to n decimal places without rounding'''
    s = '%.12f' % f
    i, p, d = s.partition('.')
    return '.'.join([i, (d+'0'*n)[:n]])

व्याख्या

अंतर्निहित विधि का मूल मूल्य को पूर्ण सटीकता पर एक स्ट्रिंग में परिवर्तित करना है और फिर वर्णों की वांछित संख्या से परे सब कुछ काट देना है। बाद वाला कदम आसान है; यह या तो स्ट्रिंग हेरफेर के साथ किया जा सकता है

i, p, d = s.partition('.')
'.'.join([i, (d+'0'*n)[:n]])

या decimalमॉड्यूल

str(Decimal(s).quantize(Decimal((0, (1,), -n)), rounding=ROUND_DOWN))

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

0011111111010011001100110011001100110011001100110011001100110011

यह 0.3 का निकटतम मूल्य है जिसे आईईईई फ्लोट के रूप में सटीक रूप से दर्शाया जा सकता है। लेकिन अगर आप 0.29999999999999998पायथन प्रोग्राम में लिखते हैं , तो कंपाइलर इसका ठीक उसी मूल्य में अनुवाद करता है । एक मामले में, आप इसका मतलब के रूप में (एक अंक के लिए) काट दिया जाना चाहिए 0.3, जबकि दूसरे मामले में आप इसे के रूप में छोटा किया जाना था 0.2, लेकिन पायथन केवल एक ही जवाब दे सकता है। यह पायथन की एक मौलिक सीमा है, या वास्तव में आलसी मूल्यांकन के बिना किसी भी प्रोग्रामिंग भाषा। ट्रंकेशन फ़ंक्शन में केवल कंप्यूटर की मेमोरी में संग्रहीत बाइनरी मूल्य तक पहुंच होती है, न कि स्ट्रिंग जिसे आपने वास्तव में स्रोत कोड में टाइप किया था। 1

यदि आप बिट्स के अनुक्रम को एक दशमलव संख्या में वापस करते हैं, तो फिर से IEEE 64-बिट फ़्लोटिंग-पॉइंट प्रारूप का उपयोग करके, आपको मिलता है

0.2999999999999999888977697537484345957637...

इतनी भोली कार्यान्वयन के साथ आएंगे 0.2, हालांकि यह संभव नहीं है कि आप क्या चाहते हैं। फ्लोटिंग-पॉइंट प्रतिनिधित्व त्रुटि पर अधिक के लिए, पायथन ट्यूटोरियल देखें

यह एक फ़्लोटिंग-पॉइंट मान के साथ काम करने के लिए बहुत दुर्लभ है जो एक गोल संख्या के करीब है और फिर भी जानबूझकर उस गोल संख्या के बराबर नहीं है। इसलिए जब काट-छाँट की जाती है, तो संभवत: यह समझ में आता है कि "निकस्ट" दशमलव प्रतिनिधित्व को सभी में से चुनें जो स्मृति में मूल्य के अनुरूप हो। पायथन 2.7 और ऊपर (लेकिन 3.0 नहीं) में बस करने के लिए एक परिष्कृत एल्गोरिथ्म शामिल है , जिसे हम डिफ़ॉल्ट स्ट्रिंग स्वरूपण ऑपरेशन के माध्यम से एक्सेस कर सकते हैं।

'{}'.format(f)

एकमात्र चेतावनी यह है कि यह gप्रारूप विनिर्देश की तरह काम करता है, इस अर्थ में कि यह घातीय संकेतन ( 1.23e+4) का उपयोग करता है यदि संख्या बड़ी या छोटी है। तो विधि को इस मामले को पकड़ना होगा और इसे अलग तरीके से संभालना होगा। ऐसे कुछ मामले हैं जहां fप्रारूप विनिर्देश का उपयोग करने के बजाय एक समस्या पैदा होती है, जैसे कि 3e-10परिशुद्धता के 28 अंकों को कम करने की कोशिश करना (यह पैदा करता है 0.0000000002999999999999999980), और मुझे अभी तक यकीन नहीं है कि उन को कैसे संभालना सबसे अच्छा है।

यदि आप वास्तव में ऐसेfloat s के साथ काम कर रहे हैं जो गोल संख्याओं के बहुत करीब हैं, लेकिन जानबूझकर उनके बराबर नहीं हैं (जैसे 0.29999999999999998 या 99.9599999999994), तो यह कुछ गलत सकारात्मक का उत्पादन करेगा, अर्थात यह उन गोल संख्याओं का निर्माण कर सकता है जिन्हें आप गोल नहीं करना चाहते थे। उस मामले में समाधान एक निश्चित परिशुद्धता निर्दिष्ट करना है।

'{0:.{1}f}'.format(f, sys.float_info.dig + n + 2)

यहां उपयोग करने के लिए सटीक अंकों की संख्या वास्तव में मायने नहीं रखती है, यह केवल यह सुनिश्चित करने के लिए पर्याप्त होना चाहिए कि स्ट्रिंग रूपांतरण में किए गए किसी भी गोलाई को इसके अच्छे दशमलव प्रतिनिधित्व के लिए "टक्कर" नहीं होती है। मुझे लगता है कि sys.float_info.dig + n + 2सभी मामलों में पर्याप्त हो सकता है, लेकिन यदि ऐसा नहीं 2किया जा सकता है, तो इसे बढ़ाना पड़ सकता है, और ऐसा करने में दुख नहीं होता।

पायथन के पहले के संस्करणों में (2.6, या 3.0 तक), फ़्लोटिंग पॉइंट संख्या स्वरूपण बहुत अधिक क्रूड था, और नियमित रूप से इस तरह की चीजें

>>> 1.1
1.1000000000000001

यदि यह आपकी स्थिति है, यदि आप छंटनी के लिए "अच्छा" दशमलव अभ्यावेदन का उपयोग करना चाहते हैं , तो आप जो कर सकते हैं (जहां तक ​​मुझे पता है) अंकों की कुछ संख्या चुन सकते हैं, पूर्ण परिशुद्धता से कम float, और पूर्णांक से इसे रौंदने से पहले कई अंकों की संख्या। एक विशिष्ट पसंद 12 है,

'%.12f' % f

लेकिन आप इसे उन संख्याओं के अनुरूप समायोजित कर सकते हैं जो आप उपयोग कर रहे हैं।


1 अच्छा ... मैंने झूठ बोला। तकनीकी रूप से, आप पायथन को अपने स्वयं के स्रोत कोड को फिर से पार्स करने का निर्देश दे सकते हैं और ट्रंकेशन फ़ंक्शन में जाने वाले पहले तर्क के अनुरूप भाग निकाल सकते हैं। यदि वह तर्क एक फ्लोटिंग-पॉइंट शाब्दिक है, तो आप इसे दशमलव बिंदु के बाद निश्चित संख्या में काट सकते हैं और वापस कर सकते हैं। हालाँकि यह रणनीति काम नहीं करती है यदि तर्क एक चर है, जो इसे काफी बेकार बनाता है। निम्नलिखित केवल मनोरंजन मूल्य के लिए प्रस्तुत किया गया है:

def trunc_introspect(f, n):
    '''Truncates/pads the float f to n decimal places by looking at the caller's source code'''
    current_frame = None
    caller_frame = None
    s = inspect.stack()
    try:
        current_frame = s[0]
        caller_frame = s[1]
        gen = tokenize.tokenize(io.BytesIO(caller_frame[4][caller_frame[5]].encode('utf-8')).readline)
        for token_type, token_string, _, _, _ in gen:
            if token_type == tokenize.NAME and token_string == current_frame[3]:
                next(gen) # left parenthesis
                token_type, token_string, _, _, _ = next(gen) # float literal
                if token_type == tokenize.NUMBER:
                    try:
                        cut_point = token_string.index('.') + n + 1
                    except ValueError: # no decimal in string
                        return token_string + '.' + '0' * n
                    else:
                        if len(token_string) < cut_point:
                            token_string += '0' * (cut_point - len(token_string))
                        return token_string[:cut_point]
                else:
                    raise ValueError('Unable to find floating-point literal (this probably means you called {} with a variable)'.format(current_frame[3]))
                break
    finally:
        del s, current_frame, caller_frame

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


हम इस फ़ंक्शन को डेटाफ़्रेम में कैसे लागू कर सकते हैं?
कोडलॉर्ड

@RohithRNair मेरे सिर के ऊपर से, उसी तरह आप किसी भी अन्य फ़ंक्शन को लागू करेंगे जो व्यक्तिगत तत्वों (यानी applymap()) पर संचालित होता है । हो सकता है कि पूरे ऑपरेशन को और अधिक कुशल बनाने का एक तरीका हो, लेकिन यह एक अलग सवाल का विषय होगा।
डेविड जेड

अप्लाईमैप () में काफी समय लग रहा है क्योंकि मेरे डेटाफ्रेम वास्तव में बड़े हैं। मैं मतभेदों के लिए दो डेटाफ्रेम की तुलना करने की कोशिश कर रहा हूं, लेकिन फ्लोटिंग पॉइंट सटीक वांछित से मेरे आउटपुट को तिरछा कर रहा है। जैसा आपने कहा, मैं उसी के लिए एक अलग प्रश्न उठाऊंगा। धन्यवाद।
कोडलॉर्ड जूल

@RohithRNair आह, अगर आप मतभेदों के लिए दो डेटाफ्रेम की तुलना करने की कोशिश कर रहे हैं, तो इसके बजाय इसके बारे में पूछें। मूल्यों को रौंदना (जो कि यह सवाल है) इसके लिए सबसे अच्छा तरीका नहीं है।
डेविड जेड

बस एक नोट, आपका कोड ऋणात्मक संख्याओं को ऋणात्मक शून्य में काट देता है, जो भ्रमित हो सकता है ...
user541686

152
round(1.923328437452, 3)

मानक प्रकारों पर अजगर के प्रलेखन देखें । राउंड फंक्शन में जाने के लिए आपको थोड़ा स्क्रॉल डाउन करना होगा। अनिवार्य रूप से दूसरी संख्या कहती है कि इसे घूमने के लिए कितने दशमलव स्थान हैं।


49
मेरा मतलब है कि मेरी जरूरत नहीं है। मुझे ट्रंकटिंग की जरूरत है, जो अलग है।
जोन वेंज

1
अहह, काफी गोरा। मेरी गलती क्षमा करें।
Teifion

22
यह एक गलत समाधान के लिए बहुत सारे बदलाव है! उन अजीब Stackoverflow दुर्लभताओं में से एक। मुझे आश्चर्य है कि अगर इसके लिए एक बिल्ला है ...
tumultous_rooster

5
यह केवल इस सवाल के लिए कितने गलत जवाब (और गलत जवाब के लिए upvotes) है।
nullstellensatz

6
बहुत से लोग इस पृष्ठ पर आते हैं जो गोलाई लिए हुए;)
जंज़ाकसन

33

परिणाम roundएक फ्लोट है, इसलिए बाहर देखें (उदाहरण पायथन 2.6 से है):

>>> round(1.923328437452, 3)
1.923
>>> round(1.23456, 3)
1.2350000000000001

स्वरूपित स्ट्रिंग का उपयोग करते समय आप बेहतर बंद हो जाएंगे:

>>> "%.3f" % 1.923328437452
'1.923'
>>> "%.3f" % 1.23456
'1.235'

8
मेरी पायथन पर, वह दौर: '% .3f'% 1.23456 == '1.235'
डेविड जेड

यह मैनुअल स्ट्रिंग प्रारूपण बकवास, अच्छी पोस्ट की तुलना में अधिक सुरुचिपूर्ण है!
rsethc

round(1.23456, 3)है 1.235और नहीं1.2350000000000001
अहमद

1
@ अहद जरूरी नहीं। यहाँ उदाहरण पाइथन 2.6 से है (उत्तर की तारीख पर ध्यान दें)। पायथन 2.7 / 3.1 में स्ट्रिंग स्वरूपण में सुधार किया गया था, शायद इसीलिए आपको अलग-अलग परिणाम मिले। फिर भी, फ़्लोटिंग पॉइंट नंबरों में अक्सर अप्रत्याशित स्ट्रिंग अभ्यावेदन होंगे, देखें: docs.python.org/3.6/tutorial/floatingpoint.html
फर्डिनेंड बेयर

21
n = 1.923328437452
str(n)[:4]

3
सरल और पायथोनिक। 4 पूरे संख्या का आकार है, हालांकि, डॉट के बाद अंक ही नहीं।
GaTTaCa

4
इसलिए यदि उपयोगकर्ता उदाहरण के लिए प्रवेश करता है 2, तो आपके पास .स्ट्रिंग के अंत में एक दशमलव डॉट होगा - वास्तव में एक अच्छा समाधान नहीं जो मुझे लगता है।
ज़ेल्फ़िर कलस्तहल

यह इस संख्या के मामले के लिए विशिष्ट है। यह 11.923328437452 पर कैसे सामान्य होगा?
ध्रुवीकरण करें

सबसे बढ़िया उत्तर! आप एक नंबर लौटाने के लिए फ्लोट () भी जोड़ सकते हैं: फ्लोट (str (n) [: 4])
justsaid

14

मेरी पायथन 2.7 प्रॉम्प्ट पर:

>>> int(1.923328437452 * 1000)/1000.0 1.923


11

सरल अजगर लिपि -

n = 1.923328437452
n = float(int(n * 1000))
n /=1000

3
साफ जवाब। आप बस एक कदम याद करते हैं, 1000 से विभाजित करने से पहले फ्लोट में वापस बदलने के लिए। अन्यथा, आपको 1. मिलेगा
योहन ओबैदिया

9
def trunc(num, digits):
   sp = str(num).split('.')
   return '.'.join([sp[0], sp[1][:digits]])

यह काम करना चाहिए। यह आपको वह छंटनी देनी चाहिए जिसकी आप तलाश कर रहे हैं।


9

इसे करने का ट्रूथली पाइथोनिक तरीका है

from decimal import *

with localcontext() as ctx:
    ctx.rounding = ROUND_DOWN
    print Decimal('1.923328437452').quantize(Decimal('0.001'))

या इससे कम:

from decimal import Decimal as D, ROUND_DOWN

D('1.923328437452').quantize(D('0.001'), rounding=ROUND_DOWN)

अपडेट करें

आमतौर पर समस्या ट्रंकिंग फ्लोट्स में ही नहीं होती है, बल्कि राउंडिंग से पहले फ्लोट नंबरों के अनुचित उपयोग में होती है ।

उदाहरण के लिए: int(0.7*3*100)/100 == 2.09 :।

यदि आप फ़्लोट्स का उपयोग करने के लिए मजबूर हैं (कहते हैं, आप अपने कोड को तेज कर रहे हैं numba), तो कीमतों के "आंतरिक प्रतिनिधित्व" के रूप में सेंट का उपयोग करना बेहतर है: ( 70*3 == 210) और इनपुट / आउटपुट को गुणा / विभाजित करें।


यह पूछने के लिए मुझे क्षमा करें, लेकिन ... क्यों?
अंकनकर्ता

@markroxor, निश्चित रूप से नहीं कि आप के बारे में क्या पूछ रहे हैं। एक सिडेनोट के रूप में, आमतौर पर समस्या राउंडिंग के साथ ही नहीं होती है, लेकिन राउंडिंग से पहले फ्लोट नंबरों के अनुचित उपयोग के साथ । जैसे int(0.7*3*100)/100 == 2.09। मेरा 1 प्रतिशत कहां गया?
एंटनी हैचकिंस

यह समझ में आता है, क्या आप इस स्पष्टीकरण के साथ अपना जवाब संपादित कर सकते हैं? धन्यवाद।
मार्कसॉर

हो रही है ImportError: cannot import name 'D', मेरा मानना ​​है कि आप नामांकित आयात नहीं करना चाहते थे?
ओवरड्रिव

8

तो इस प्रश्न के लिए दिए गए कई उत्तर पूरी तरह से गलत हैं। वे या तो फ़्लोट अप (ट्रंकट के बजाय) राउंड करते हैं या सभी मामलों के लिए काम नहीं करते हैं।

यह शीर्ष Google परिणाम है जब मैं 'पायथन ट्रंकट फ्लोट' के लिए खोज करता हूं, एक अवधारणा जो वास्तव में सीधी है, और जो बेहतर उत्तर की हकदार है। मैं हैचकिंस से सहमत हूं कि decimalमॉड्यूल का उपयोग करना ऐसा करने का pythonic तरीका है, इसलिए मैं यहां एक फ़ंक्शन देता हूं जो मुझे लगता है कि सवाल का सही उत्तर देता है, और जो सभी मामलों के लिए अपेक्षा के अनुरूप काम करता है।

साइड-नोट के रूप में, भिन्नात्मक मूल्यों, सामान्य रूप से, बाइनरी फ़्लोटिंग पॉइंट वेरिएबल्स (इसे यहां चर्चा के लिए देखें ) द्वारा बिल्कुल प्रतिनिधित्व नहीं किया जा सकता है , यही कारण है कि मेरा फ़ंक्शन एक स्ट्रिंग लौटाता है।

from decimal import Decimal, localcontext, ROUND_DOWN

def truncate(number, places):
    if not isinstance(places, int):
        raise ValueError("Decimal places must be an integer.")
    if places < 1:
        raise ValueError("Decimal places must be at least 1.")
    # If you want to truncate to 0 decimal places, just do int(number).

    with localcontext() as context:
        context.rounding = ROUND_DOWN
        exponent = Decimal(str(10 ** - places))
        return Decimal(str(number)).quantize(exponent).to_eng_string()

4

मैंने कुछ इस तरह किया:

from math import trunc


def truncate(number, decimals=0):
    if decimals < 0:
        raise ValueError('truncate received an invalid value of decimals ({})'.format(decimals))
    elif decimals == 0:
        return trunc(number)
    else:
        factor = float(10**decimals)
        return trunc(number*factor)/factor

4

तुम कर सकते हो:

def truncate(f, n):
    return math.floor(f * 10 ** n) / 10 ** n

परिक्षण:

>>> f=1.923328437452
>>> [truncate(f, n) for n in range(5)]
[1.0, 1.9, 1.92, 1.923, 1.9233]

यह केवल सकारात्मक संख्याओं के साथ छोटा हो जाता है, नकारात्मक संख्या नीचे (शून्य से दूर) हो जाएगी।
आरोन डी

3

यदि आप कुछ गणितज्ञ हैं, तो यह + ve संख्याओं के लिए काम करता है:

>>> v = 1.923328437452
>>> v - v % 1e-3
1.923

जैसा कि मैं समझता हूं कि 1e-3 डॉट के बाद 3 अंकों तक पहुंच जाएगा। मुझे यह उत्तर पसंद आया लेकिन यह 4 और 5 के लिए काम नहीं करता है
जैसे

2

एक पांडा df का उपयोग करते समय इसने मेरे लिए काम किया

import math
def truncate(number, digits) -> float:
    stepper = 10.0 ** digits
    return math.trunc(stepper * number) / stepper

df['trunc'] = df['float_val'].apply(lambda x: truncate(x,1))
df['trunc']=df['trunc'].map('{:.1f}'.format)

1

बस यह उल्लेख करना चाहता था कि पुराने "फर्श के साथ () फर्श ()" की चाल है

round(f) = floor(f+0.5)

दौर () से मंजिल बनाने के लिए चारों ओर मोड़ दिया जा सकता है ()

floor(f) = round(f-0.5)

यद्यपि ये दोनों नियम नकारात्मक संख्याओं के आसपास हैं, इसलिए इसका उपयोग करना आदर्श से कम है:

def trunc(f, n):
    if f > 0:
        return "%.*f" % (n, (f - 0.5*10**-n))
    elif f == 0:
        return "%.*f" % (n, f)
    elif f < 0:
        return "%.*f" % (n, (f + 0.5*10**-n))

1

पूर्णांक (16.5); यह 16 का पूर्णांक मान देगा, यानी ट्रंक, दशमलव निर्दिष्ट करने में सक्षम नहीं होगा, लेकिन लगता है कि आप ऐसा कर सकते हैं

import math;

def trunc(invalue, digits):
    return int(invalue*math.pow(10,digits))/math.pow(10,digits);

1

यहाँ एक आसान तरीका है:

def truncate(num, res=3):
    return (floor(num*pow(10, res)+0.5))/pow(10, res)

num = 1.923328437452 के लिए, यह 1.923 आउटपुट करता है



1

उपयोग करने के लिए एक सामान्य और सरल कार्य:

def truncate_float(number, length):
    """Truncate float numbers, up to the number specified
    in length that must be an integer"""

    number = number * pow(10, length)
    number = int(number)
    number = float(number)
    number /= pow(10, length)
    return number

महान! इंट टू कास्ट पॉजिटिव और नेगेटिव दोनों नंबरों को काट देता है।
आरोन डी

1

पाइथन में एक आसान वर्कअराउंड है 3. जहां कटौती करने के लिए मैंने एक मदद चर डिकम्प्लस के साथ परिभाषित किया है ताकि इसे आसानी से अनुकूलित किया जा सके।

f = 1.12345
decPlace= 4
f_cut = int(f * 10**decPlace) /10**decPlace

आउटपुट:

f = 1.1234

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


1
def precision(value, precision):
    """
    param: value: takes a float
    param: precision: int, number of decimal places
    returns a float
    """
    x = 10.0**precision
    num = int(value * x)/ x
    return num
precision(1.923328437452, 3)

1.923


अच्छा लगा लेकिन आप गोल नहीं हो रहे हैं।
एलेक्स

1

लघु और आसान संस्करण

def truncate_float(value, digits_after_point=2):
    pow_10 = 10 ** digits_after_point
    return (float(int(value * pow_10))) / pow_10

>>> truncate_float(1.14333, 2)
>>> 1.14

>>> truncate_float(1.14777, 2)
>>> 1.14


>>> truncate_float(1.14777, 4)
>>> 1.1477

1

ज्यादातर जवाब रास्ता मेरी राय में बहुत जटिल हैं, इस बारे में कैसे?

digits = 2  # Specify how many digits you want

fnum = '122.485221'
truncated_float = float(fnum[:fnum.find('.') + digits + 1])

>>> 122.48

बस 'के सूचकांक के लिए स्कैनिंग।' और वांछित (कोई गोलाई नहीं) के रूप में छोटा करें। अंतिम चरण के रूप में फ्लोट में स्ट्रिंग बदलें।

या आपके मामले में अगर आपको इनपुट के रूप में एक फ्लोट मिलता है और आउटपुट के रूप में एक स्ट्रिंग चाहिए:

fnum = str(122.485221)  # convert float to string first
truncated_float = fnum[:fnum.find('.') + digits + 1]  # string output

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

1
>>> floor((1.23658945) * 10**4) / 10**4
1.2365

# वांछित अंकों के 10 ** संख्या से विभाजित और गुणा करें


0

numpy.round का उपयोग करें

import numpy as np
precision = 3
floats = [1.123123123, 2.321321321321]
new_float = np.round(floats, precision)

0

सूची-बोध में फिट होने के लिए कुछ सरल है, जिसमें कोई पुस्तकालय या अन्य बाहरी निर्भरता नहीं है। पायथन> = 3.6 के लिए, एफ-स्ट्रिंग्स के साथ लिखना बहुत सरल है।

विचार यह है कि स्ट्रिंग-रूपांतरण को अपनी आवश्यकता से अधिक स्थान पर गोलाई देना और फिर अंतिम अंक काट देना।

>>> nout = 3  # desired number of digits in output
>>> [f'{x:.{nout+1}f}'[:-1] for x in [2/3, 4/5, 8/9, 9/8, 5/4, 3/2]]
['0.666', '0.800', '0.888', '1.125', '1.250', '1.500']

बेशक, वहाँ है यहाँ (चौथा अंकों के लिए अर्थात्) हो रहा गोलाई, लेकिन गोलाई कुछ बिंदु पर unvoidable है। ट्रंकेशन और राउंडिंग के बीच संक्रमण प्रासंगिक है, यहां इसका थोड़ा बेहतर उदाहरण है:

>>> nacc = 6  # desired accuracy (maximum 15!)
>>> nout = 3  # desired number of digits in output
>>> [f'{x:.{nacc}f}'[:-(nacc-nout)] for x in [2.9999, 2.99999, 2.999999, 2.9999999]]
>>> ['2.999', '2.999', '2.999', '3.000']

बोनस: सही पर शून्य हटा रहा है

>>> nout = 3  # desired number of digits in output
>>> [f'{x:.{nout+1}f}'[:-1].rstrip('0') for x in [2/3, 4/5, 8/9, 9/8, 5/4, 3/2]]
['0.666', '0.8', '0.888', '1.125', '1.25', '1.5']

0

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

def trunc(num, digits):
    l = str(float(num)).split('.')
    digits = min(len(l[1]), digits)
    return (l[0]+'.'+l[1][:digits])

जिसे यहां और यहां पाए जाने वाले सभी कोने के मामलों का ध्यान रखना चाहिए ।


-1

एक अजगर नौसिखिया भी हूं और यहां कुछ बिट्स और टुकड़ों का उपयोग करने के बाद, मैं अपने दो सेंट पेश करता हूं

print str(int(time.time()))+str(datetime.now().microsecond)[:3]

str (int (time.time ())) समय को int के रूप में लेगा और इसे string में रूपांतरित करेगा और साथ देगा ... str (datetime.now ()। microsecond) [: 3] जो केवल microseconds को लौटाता है, कन्वर्ट करता है। स्ट्रिंग और पहले 3 वर्णों को काटें



-3

यदि आप प्रिंट करते समय मतलब रखते हैं, तो निम्नलिखित काम करना चाहिए:

print '%.3f' % number

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