ছিটানো পাইথনে ভাসছে


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পাইথন প্রোগ্রামে লিখেন , সংকলকটি আইইইইই ফ্লোটিং-পয়েন্ট ফর্ম্যাটটি বিটগুলির ক্রম অনুসারে এনকোড করে (64৪-বিট ফ্লোট ধরে)

0011111111010011001100110011001100110011001100110011001100110011

এটি 0.3 এর নিকটতম মান যা সঠিকভাবে কোনও আইইইই ফ্লোট হিসাবে প্রতিনিধিত্ব করতে পারে। তবে আপনি যদি 0.29999999999999998পাইথন প্রোগ্রামে লিখেন , সংকলক একে একে একে একই মান হিসাবে অনুবাদ করবে । একটি ক্ষেত্রে আপনি বোঝাতে চেয়েছিলেন যে এটি কেটে নেওয়া হয়েছে (এক অঙ্কে) 0.3, অন্য ক্ষেত্রে আপনি বোঝাতে চেয়েছিলেন এটি কেটে ফেলা হয়েছে 0.2তবে পাইথন কেবল একটি উত্তর দিতে পারে। এটি পাইথনের একটি মৌলিক সীমাবদ্ধতা, বা অলস মূল্যায়ন ছাড়া সত্যই কোনও প্রোগ্রামিং ভাষা। কাটা ফাংশনটির কেবলমাত্র কম্পিউটারের মেমোরিতে সংরক্ষিত বাইনারি মানটিতে অ্যাক্সেস থাকে, আপনি সোর্স কোডে টাইপ করেন এমন স্ট্রিং নয়। 1

আপনি যদি বিটের ক্রমটিকে দশমিক সংখ্যায় আবার ডিকোড করেন, আবার আইইইই 64৪-বিট ফ্লোটিং-পয়েন্ট ফর্ম্যাট ব্যবহার করে আপনি পান

0.2999999999999999888977697537484345957637...

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

একটি ভাসমান-পয়েন্ট মানের সাথে কাজ করা খুব বিরল যা কোনও গোলাকার সংখ্যার খুব কাছাকাছি এবং তবুও ইচ্ছাকৃতভাবে round বৃত্তাকার সংখ্যার সমান নয়। সুতরাং সংক্ষিপ্তকরণ করার সময়, মেমরির মানটির সাথে সামঞ্জস্য হতে পারে এমন সমস্তগুলির মধ্যে "সেরা" দশমিক প্রতিনিধিত্ব চয়ন করা বোধগম্য হয়। পাইথন ২.7 এবং তার উপরে (তবে 3.0.০ নয়) কেবলমাত্র এটি করার জন্য একটি পরিশীলিত অ্যালগরিদম অন্তর্ভুক্ত রয়েছে , যা আমরা ডিফল্ট স্ট্রিং বিন্যাসকরণ ক্রিয়াকলাপের মাধ্যমে অ্যাক্সেস করতে পারি।

'{}'.format(f)

কেবলমাত্র সতর্কতাই হ'ল এটি একটি gফর্ম্যাট স্পেসিফিকেশনের মতো কাজ করে, এই 1.23e+4সংখ্যায় যে এটি সংখ্যাটি বড় বা যথেষ্ট ছোট হলে এটি সূচকীয় স্বরলিপি ব্যবহার করে ( )। সুতরাং পদ্ধতিতে এই কেসটি ধরতে হবে এবং এটি অন্যরকমভাবে পরিচালনা করতে হবে। কয়েকটি ক্ষেত্রে রয়েছে যেখানে fপরিবর্তে ফর্ম্যাট স্পেসিফিকেশন ব্যবহার করা সমস্যার কারণ হয়ে থাকে যেমন 3e-10২৮ ডিজিটের যথার্থতার সংক্ষিপ্তকরণের চেষ্টা করা (এটি উত্পন্ন করে 0.0000000002999999999999999980) এবং সেগুলি কীভাবে পরিচালনা করা যায় তা আমি এখনও নিশ্চিত নই।

আপনি যদি আসলে এমনfloat গুলি নিয়ে কাজ করছেন যা রাউন্ড সংখ্যার খুব নিকটবর্তী তবে ইচ্ছাকৃতভাবে তাদের সমান নয় (যেমন 0.29999999999999998 বা 99.959999999999994), এটি কিছু মিথ্যা ধনাত্মকতা তৈরি করবে, অর্থাত্ এটি গোলাকার সংখ্যা নয় যা আপনি গোল করতে চান নি। সেক্ষেত্রে সমাধানটি একটি নির্দিষ্ট নির্ভুলতা নির্দিষ্ট করে।

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

নির্ভুলতার অঙ্কগুলি এখানে ব্যবহারের পক্ষে সত্যিকার অর্থে কিছু আসে যায় না, স্ট্রিং রূপান্তরটিতে যে কোনও রাউন্ডিং করা হয় তার দশমিক উপস্থাপনার মানটি "বাম্প" না করে তা নিশ্চিত করার জন্য এটি পর্যাপ্ত পরিমাণে বড় হওয়া দরকার। আমি মনে করি sys.float_info.dig + n + 2সব ক্ষেত্রেই যথেষ্ট হতে পারে, তবে তা না হলে 2বাড়ানো হতে পারে এবং এটি করতে ক্ষতি হয় না।

পাইথনের পূর্ববর্তী সংস্করণগুলিতে (২.6 বা ৩.০ অবধি) ভাসমান পয়েন্ট সংখ্যা বিন্যাসটি অনেক বেশি অপরিশোধিত ছিল এবং নিয়মিত এগুলি তৈরি করে

>>> 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

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


কীভাবে আমরা এই ফাংশনটি ডেটাফ্রেমে প্রয়োগ করতে পারি?
কোডলর্ড

@ রোহিতআরনেয়ার আমার মাথার উপরের অংশটি ঠিক একইভাবে আপনি পৃথক উপাদানগুলিতে (যেমন applymap()) চালিত অন্য কোনও ফাংশন প্রয়োগ করতে চান । পুরো অপারেশনটিকে আরও দক্ষ করার একটি উপায় থাকতে পারে তবে এটি একটি পৃথক প্রশ্নের জন্য বিষয়।
ডেভিড জেড

অ্যাপ্লিকেশন () আমার ডেটাফ্রেমগুলি সত্যিই বড় হওয়ায় অনেক সময় নিচ্ছে। আমি পার্থক্যের জন্য দুটি ডেটাফ্রেমের তুলনা করার চেষ্টা করছি তবে ভাসমান পয়েন্ট যথার্থতা আমার আউটপুটটিকে পছন্দসই থেকে স্কিচ করছে। যেমনটি আপনি বলেছেন, আমিও এর জন্য পৃথক প্রশ্ন উত্থাপন করব। ধন্যবাদ।
কোডসর্ড

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

কেবল একটি নোট, আপনার কোডটি নেতিবাচক সংখ্যাগুলি নেতিবাচক শূন্যে
কাটবে

152
round(1.923328437452, 3)

স্ট্যান্ডার্ড ধরণের উপর পাইথনের ডকুমেন্টেশন দেখুন । রাউন্ড ফাংশনটি পেতে আপনাকে কিছুটা নিচে স্ক্রোল করতে হবে। মূলত দ্বিতীয় সংখ্যাটি বলে যে এটি কতগুলি দশমিক স্থানকে গোল করবে।


49
আমি বলতে চাইছি গোল করা আমার যা প্রয়োজন তা নয়। আমার কাটা কাটা দরকার, যা আলাদা।
জোয়ান ভ্যাঞ্জ

1
আহ, যথেষ্ট ন্যায্য। আমার ভুল দুঃখিত।
টিফিওন

22
এটি একটি ভুল সমাধানের জন্য অনেক প্রচুর লক্ষ্য! সেই অদ্ভুত স্ট্যাকওভারফ্লো বিরলতার মধ্যে একটি। আমি ভাবছি এটা জন্য একটি ব্যাজ যদি ...
tumultous_rooster

5
এই প্রশ্নের জন্য কতগুলি ভুল উত্তর (এবং ভুল উত্তরগুলির জন্য সমর্থন) কেবলই ভয়াবহ।
nullstellensatz

6
রাউন্ডিং খুঁজছেন এই পৃষ্ঠায় প্রচুর লোক আসবে;)
জাঞ্জাকসন

33

এর ফলাফলটি roundএকটি ভাসা, তাই নজর রাখুন (উদাহরণটি পাইথন ২.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
@ আহমাদ অগত্যা নয়। এখানে উদাহরণ পাইথন ২.6 থেকে (উত্তরের তারিখটি নোট করুন)। পাইথন ২.7 / ৩.১-এ স্ট্রিং ফর্ম্যাটিংয়ের উন্নতি করা হয়েছিল, এ কারণেই আপনি বিভিন্ন ফলাফল পেতে পারেন। তবুও, ভাসমান পয়েন্ট সংখ্যাগুলিতে প্রায়শই অপ্রত্যাশিত স্ট্রিং উপস্থাপনা থাকবে: দেখুন: ডকস.পিথন.অর্গ
ফার্ডিনান্দ বায়ার

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

3
সাধারণ এবং পাইথোনিক। 4 যদিও পুরো সংখ্যার আকার, বিন্দুর পরে কেবল অঙ্কগুলিই নয়।
গাট্টাকা

4
সুতরাং যদি ব্যবহারকারী উদাহরণস্বরূপ প্রবেশ করে 2, আপনার .স্ট্রিংয়ের শেষে দশমিক ডট থাকবে - আমি মনে করি এটির পক্ষে ভাল সমাধান নয়।
জেলফির কাল্টসটাহল

এটি এই সংখ্যার ক্ষেত্রে একটি ক্ষেত্রে নির্দিষ্ট। এটি কীভাবে 11.923328437452 এ সাধারণী হবে?
পোলারাইজ করুন

সর্বোত্তম উত্তর! আপনি একটি নম্বর ফেরত করতে ভাসা () যোগ করতে পারেন: ভাসা (
টিআর

14

আমার পাইথন ২.7 প্রম্পটে:

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


11

সাধারণ অজগর লিপি -

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

3
পরিষ্কার উত্তর। আপনি শুধু এক ধাপ মিস্, অন্যথায় 1000. দ্বারা বিভাজক সামনে ভাসা ফিরে রূপান্তর করতে, আপনি পাবেন 1.
ইয়োহান Obadia

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) এবং ইনপুট / আউটপুটগুলিকে গুণিত / ভাগ করে।


আমাকে জিজ্ঞাসা করার জন্য পার্সন, কিন্তু ... কেন?
মার্কক্রক্সোর

@মার্ক্রক্সর, আপনি ঠিক কী সম্পর্কে জিজ্ঞাসা করছেন তা নিশ্চিত নয়। সাইডেনোট হিসাবে, সাধারণত সমস্যাটি গোলটি নিজেই হয় না, তবে রাউন্ডিংয়ের আগে ভাসা সংখ্যার ভুল ব্যবহার করে । যেমন int(0.7*3*100)/100 == 2.09। আমার 1 সেন্ট কোথায় গেল?
অ্যান্টনি হ্যাচকিন্স

এটি বোঝা যায় যে, আপনি কি এই উত্তর দিয়ে নিজের উত্তরটি সম্পাদনা করতে পারবেন? ধন্যবাদ।
মার্ক্রোক্সোর

পথ ImportError: cannot import name 'D', আমি আপনাকে একটি নামাঙ্কিত আমদানি কোন করতে চেয়েছিলেন বিশ্বাস কর?
ওভারড্রাইভার

8

এই প্রশ্নের জন্য দেওয়া অনেক উত্তর কেবল সম্পূর্ণ ভুল। তারা হয় ভাসা ভাসা (কাটা কাটা বরং) বা সমস্ত ক্ষেত্রে কাজ করে না।

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

পার্শ্ব-নোট হিসাবে, ভগ্নাংশগত মানগুলি, সাধারণত, বাইনারি ভাসমান বিন্দু ভেরিয়েবলগুলি দ্বারা ঠিক উপস্থাপন করা যায় না (এটির আলোচনার জন্য এখানে দেখুন ), যার কারণে আমার ফাংশনটি স্ট্রিং দেয় returns

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

একটি পান্ডাস ডিএফ ব্যবহার করার সময় এটি আমার জন্য কাজ করেছিল

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

int- এ (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)

নাম্বার জন্য = 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

গ্রেট! কাস্ট টু ইন্টার ধনাত্মক এবং negativeণাত্মক উভয় সংখ্যাকে ছিন্ন করে।
হারুন ডি

1

পাইথন 3 এ একটি সহজ কাজ রয়েছে Where কোথায় কাটা যায় আমি কোনও সহায়ক পরিবর্তনশীল ডেস্প্লেসটিকে অভিযোজিত করতে সহজ করার সাথে সংজ্ঞায়িত করেছি।

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

আউটপুট:

f = 1.1234

আশা করি এটা সাহায্য করবে.



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']

অবশ্যই, সেখানে হয় এখানে (চতুর্থ অঙ্ক জন্য যেমন) ঘটছে rounding কিন্তু rounding কিছু সময়ে 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 (সময়.টাইম ()) সময়কে যুগের পূর্বে হিসাবে গ্রহণ করবে এবং এটিকে স্ট্রিংয়ে রূপান্তর করবে এবং ... স্ট্রিম (ডেটটাইম.নো ()। মাইক্রোসেকেন্ড) এর সাথে যোগ দেবে [: 3] যা কেবলমাত্র মাইক্রোসেকেন্ডগুলি ফেরত দেয়, রূপান্তর করে স্ট্রিং এবং প্রথম 3 টি অক্ষরে কাটা



-3

মুদ্রণের সময় যদি আপনি বোঝাতে চান, তবে নিম্নলিখিতগুলির কাজ করা উচিত:

print '%.3f' % number

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