পাইথনের উল্লেখযোগ্য পরিসংখ্যানগুলিতে কোনও সংখ্যাকে কীভাবে গোল করবেন


148

ইউআইতে প্রদর্শিত হওয়ার জন্য আমার একটি ভাসা গোল করতে হবে। উদাহরণস্বরূপ, একটি গুরুত্বপূর্ণ ব্যক্তির কাছে:

1234 -> 1000

0.12 -> 0.1

0.012 -> 0.01

0.062 -> 0.06

6253 -> 6000

1999 -> 2000

পাইথন লাইব্রেরিটি ব্যবহার করে এটি করার কোনও দুর্দান্ত উপায় আছে, বা আমার নিজের এটি লিখতে হবে?


2
আপনি কি কেবল আউটপুট ফর্ম্যাট করছেন? আপনি এই সম্পর্কে জিজ্ঞাসা করছেন? ডকস.পাইথন.আর.লিবারি / স্টাডিটাইপস html# স্ট্রিং- ফর্ম্যাটিং বা এটি? docs.python.org/library/string.html#string- formatting
এস .লট

আপনি 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
গোল_ত__ = ল্যাম্বদা এক্স, এন: বৃত্তাকার (x, -int (তল (লগ 10 (এক্স))) + (এন - 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আপনাকে ধন্যবাদ ম্যাথ.inf এর মতো অপরিজ্ঞাত বা কোনও আবর্জনার মতো সুরক্ষিত নেই
এজেপি

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" এর ফলস্বরূপ যা ভুল। এই ব্লগ পোস্টে আরও বিশদ: র্যান্ডলেট.com
blog

3
এভজেনির উত্তরের পদ্ধতির মতোই এটি সঠিকভাবে ব্যর্থ 0.075হয় 0.08। এটি 0.07পরিবর্তে ফিরে আসে ।
গ্যাব্রিয়েল

1
round_sig = lambda f,p: float(('%.' + str(p) + 'e') % f)আপনাকে উল্লেখযোগ্য সংখ্যাগুলির সংখ্যা সামঞ্জস্য করতে দেয়!
denizb

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) -> গণিতের ডোমেন ত্রুটি, আপনি সেখানে একটি
অ্যাবস

2
এভজিনি এবং পিটার গ্রাহামের উত্তরের পদ্ধতিগুলির মতোই এটি সঠিকভাবে ব্যর্থ 0.075হয় 0.08। এটি 0.07পরিবর্তে ফিরে আসে ।
গ্যাব্রিয়েল

3
এছাড়াও এটি round_sig (0) এর জন্য ব্যর্থ হয়।
যুবাল আতজমন

2
@ গ্যাব্রিয়েল এটি আপনার কম্পিউটারে অজগরটির একটি "বৈশিষ্ট্য" অন্তর্নির্মিত এবং এটি এর ক্রিয়াকলাপের আচরণে প্রকাশ পায় rounddocs.python.org/2/tutorial/floatingPoint.html#tut-fp-issues
Novice C

1
@ গ্যাব্রিয়েল আমি একটি উত্তর যুক্ত করেছি যা ব্যাখ্যা করে যে "0.06" গোল করা থেকে আপনার কেন 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) এর সাথে সংখ্যার পার্থক্য করার কোনও আদর্শ উপায় নেই । যদি আপনার এটি করার দরকার হয়, তবে টু-স্পষ্টতা প্যাকেজটিতে সরবরাহ করা যেমন অ-মানক ফাংশন প্রয়োজন।


এফওয়াইআই: আমি আমার কোডের একটিতে একই সমস্যাটি সমাধান করার চেষ্টা করতে গিয়ে এডিজিক থেকে স্বাধীনভাবে এই সমাধানটি পেয়েছি। এখন আমি বুঝতে পেরেছি যে আমার সমাধানটি তার স্পষ্টতই প্রায় অনুরূপ (আমি কেবল ভুল ফলাফল দেখেছি এবং কোডটি পড়তে বিরক্ত করি নি, আমার ভুল)। সম্ভবত তার উত্তরের নীচে একটি সংক্ষিপ্ত মন্তব্য একটি নতুন উত্তরের পরিবর্তে যথেষ্ট হবে ... কেবলমাত্র (কী) পার্থক্য হ'ল :gবিন্যাসটির দ্বিগুণ ব্যবহার যা পূর্ণসংখ্যা সংরক্ষণ করে।
Falken

বাহ, আপনার উত্তরটি সত্যিই উপরে থেকে নীচে পর্যন্ত পড়তে হবে;) এই ডাবল-কাস্ট কৌশলটি নোংরা, তবে ঝরঝরে। (নোট যে 1999 ফরম্যাট যেমন 2000.0 প্রস্তাব দেওয়া 5 উল্লেখযোগ্য সংখ্যা, তাই এটি মধ্য দিয়ে যেতে হয়েছে {:g}আবার।) সাধারণভাবে, trailing শূন্য সঙ্গে পূর্ণসংখ্যার উল্লেখযোগ্য পরিসংখ্যান সংক্রান্ত দ্ব্যর্থক হয়, যদি না কিছু কৌশল (শেষ উল্লেখযোগ্য উপরে ঊর্ধ্বরেখা মত) ব্যবহার করা হয়।
টমাসজ গেন্ডার

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'

এখন আমি
এটির

@ মোফ আপনি সম্ভবত একটি ল্যাম্বডা সহ পান্ডাস মানচিত্র ব্যবহার করতে পারেন। lambda x: to_precision(x, 2)
উইলিয়াম রুসনাক

এটিকে ( পাইপিআই ) [ পিপআই.আর.জি.] যুক্ত করুন । যতদূর আমি বলতে পারি সেখানে এর মতো কিছুই নেই।
মুরগথ

এটি একটি দুর্দান্ত প্যাকেজ তবে আমি মনে করি বেশিরভাগ বৈশিষ্ট্যগুলি এখন সিগফিগ মডিউলে রয়েছে
HyperActive

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 উভয়ের উপস্থাপনা উভয়ই ভাসমান পয়েন্ট গণিতের সংমিশ্রণে প্রাপ্য । ০.০75৫ এর নিকটতম সংখ্যা যা প্রকৃতপক্ষে উপস্থাপন করা যেতে পারে এটি সামান্য ছোট, অতএব আপনি নির্লজ্জভাবে প্রত্যাশার চেয়ে বৃত্তাকারটি আলাদাভাবে বের হয়।

আরও মনে রাখবেন যে এটি দশমিক অ-দশমিক ভাসমান বিন্দুর গাণিতিকের ব্যবহারের ক্ষেত্রে প্রযোজ্য যেমন সি এবং জাভা উভয়েরই একই সমস্যা রয়েছে।

আরও বিশদ দেখানোর জন্য, আমরা পাইথনকে "হেক্স" ফর্ম্যাটে নম্বরটি ফর্ম্যাট করতে বলি:

0.075.hex()

যা আমাদের দেয়: 0x1.3333333333333p-4। এটি করার কারণটি হ'ল স্বাভাবিক দশমিক প্রতিনিধিত্ব প্রায়শই গোলাকার জড়িত এবং তাই কম্পিউটারটি সংখ্যাটি কীভাবে "দেখায়" তা নয়। আপনি যদি এই ফর্ম্যাটটিতে অভ্যস্ত না হন, তবে কয়েকটি দরকারী তথ্যসূত্র হলেন পাইথন ডক্স এবং সি স্ট্যান্ডার্ড

এই সংখ্যাগুলি কীভাবে কিছুটা কাজ করে তা দেখানোর জন্য, আমরা এটি করে আমাদের শুরুতে ফিরে যেতে পারি:

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

যা মুদ্রণ করা উচিত 0.07516**13দশমিক পয়েন্টের পরে 13 টি হেক্সাডেসিমাল সংখ্যা রয়েছে এবং 2**-4হেক্স এক্সপোশনগুলি বেস -২ হওয়ার কারণ এটি।

এখন ভাসমানগুলি কীভাবে প্রতিনিধিত্ব করা হয় সে সম্পর্কে আমরা কিছু ধারণা পেয়েছি আমরা 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 প্রবেশ করেন তখন আপনি প্রকৃতপক্ষে 74 0.07499 (উপরে হিসাবে) প্রবেশ করছেন, যা সাধারণ গণিতের নিয়ম অনুসারে আসে। আপনি যদি কোনও ডেটা টাইপ ( দশমিক ভাসমান পয়েন্টের মতো ) ব্যবহার করে যা 0.075 উপস্থাপন করতে পারে তবে এটি অবশ্যই 0.08 এর সাথে হওয়া উচিত
স্যাম ম্যাসন

আমি বিভ্রান্ত নই আমি যখন 0.075 লিখি আমি আসলে 0.075 এ প্রবেশ করি। কোডের অভ্যন্তরে ভাসমান পয়েন্ট গণিতে যা ঘটেছিল তা আমি পাত্তা দিই না।
গ্যাব্রিয়েল

@ গ্যাব্রিয়েল: এবং আপনি যদি ইচ্ছাকৃতভাবে প্রবেশ করে থাকেন 0.074999999999999999, তবে আপনি এই ক্ষেত্রে কী পাওয়ার আশা করবেন?
মার্ক ডিকিনসন

@ মার্কডিকিনসন যা নির্ভর করে একটি উল্লেখযোগ্য চিত্র: 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
@ পিজেভান্দেহার, আপনি সাধারণ ক্ষেত্রে সঠিক এবং আমার এটি করা উচিত ছিল। এছাড়াও, সংখ্যার গণনাগুলির জন্য আমার সম্পাদন করা দরকার আমরা মাঝে মাঝে 1e-15 এর মতো নম্বর পাই। আমাদের আবেদনে আমরা দুটি ছোট সংখ্যার (যার মধ্যে একটি শূন্য হতে পারে) এর সমতুল্য হিসাবে বিবেচনা করতে চাই। এছাড়াও কিছু লোক ছোট সংখ্যাকে (এটি 1e-9, 1e-15, বা এমনকি 1e-300 হতে পারে) শূন্য করতে চান।
ryan281

1
মজাদার. এটি ব্যাখ্যা করার জন্য ধন্যবাদ। সেক্ষেত্রে আমি এই সমাধানটি সত্যিই পছন্দ করি।
pjvandehaar

@ মুরগথ এটি একটি আকর্ষণীয় এবং কঠিন সমস্যা। আপনি উল্লেখ করেছেন যে, মুদ্রিত মান 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)) ) )

এটি কোনও স্কেলারের সংখ্যাসূচক মানের জন্য কাজ করে এবং কোনও floatকারণে যদি আপনাকে প্রতিক্রিয়া স্থানান্তর করতে হয় তবে n হতে পারে । আপনি আসলে সীমাটি এখানে চাপ দিতে পারেন:

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 সরাসরি পছন্দসই আচরণ সমর্থন করে। নিম্নলিখিত খণ্ডটি x4 টি গুরুত্বপূর্ণ ব্যক্তিকে ফ্ল্যাট ফর্ম্যাট করে বৈজ্ঞানিক স্বরলিপি দমন করে returns

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/references/generated/… এ সরানো হয়েছে ) জানায় যে এই ফাংশনটি ড্রাগন 4 অ্যালগরিদম (স্টিল অ্যান্ড হোয়াইট 1990 এর, dl.acm.org/doi/pdf/10.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

পাইথন ২.6+ নতুন স্টাইলের ফর্ম্যাটিং ব্যবহার করে (% -স্টাইলটি হ্রাস করা হয়েছে):

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

পাইথন ২.7++ এ আপনি নেতৃস্থানীয় 0গুলি বাদ দিতে পারেন ।


অজগরটির কোন সংস্করণ আছে? পাইথন 3.6.3 | অ্যানাকোন্ডা, ইনক। | (ডিফল্ট, অক্টোবর 13 2017, 12:02:49) একই পুরানো রাউন্ডিং সমস্যা রয়েছে। "{0}"। ফর্ম্যাট (ভাসমান ("{0: .1g}"। ফর্ম্যাট (0.075))) '0.07' দেয়, '0.08' নয়
ডন ম্যাক্ল্যাচলান

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

এটি স্বতন্ত্র সংখ্যা এবং ন্যালি অ্যারেগুলির জন্য কাজ করে এবং নেতিবাচক সংখ্যার জন্য সূক্ষ্মভাবে কাজ করা উচিত।

আমরা যুক্ত করতে পারি এমন আরও একটি পদক্ষেপ রয়েছে - এনপি.আউন্ড () গোলাকার একটি পূর্ণসংখ্যা হলেও দশমিক সংখ্যা ফেরায় (অর্থাত্ ফিজার্স = 2 এর জন্য আমরা ফিরে পাওয়ার আশা করতে পারি -460 তবে পরিবর্তে আমরা -460.0 পাই)। এর জন্য আমরা এই পদক্ষেপটি সংশোধন করতে পারি:

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

দুর্ভাগ্যক্রমে, এই চূড়ান্ত পদক্ষেপটি সংখ্যার অ্যারের জন্য কাজ করবে না - আমি আপনার প্রিয় পাঠককে এটির প্রয়োজন হবে কিনা তা খুঁজে বের করতে।


0

Sigfig প্যাকেজ / গ্রন্থাগার কভার করেছেন। ইনস্টল করার পরে আপনি নিম্নলিখিতগুলি করতে পারেন:

>>> from sigfig import round
>>> round(1234, 1)
1000
>>> round(0.12, 1)
0.1
>>> round(0.012, 1)
0.01
>>> round(0.062, 1)
0.06
>>> round(6253, 1)
6000
>>> round(1999, 1)
2000

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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.