পাইথন রাউন্ডের পরের সর্বোচ্চ পাওয়ার 10


44

math.ceil10 এর পরের সর্বোচ্চ পাওয়ারের জন্য একটি সংখ্যা নির্ধারিত হয় আমি কীভাবে এমন সম্পাদন করব ?

# 0.04  ->  0.1
# 0.7   ->  1
# 1.1   ->  10  
# 90    ->  100  
# ...

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


3
@ বোল্ড দেখে মনে হচ্ছে এই সমাধানগুলি এখন পর্যন্ত কাজ 10করছে, এর জন্য উদাহরণ সহ কিছু দরকার হবে log10
jonrsharpe

3
আপনি যে শব্দটি চান তা হ'ল "শক্তি"। আপনার নিজের ভাষাটির শব্দের জন্য আপনি ভুল অনুবাদ পেয়েছেন।
ব্যবহারকারী 2357112 মনিকা

ধন্যবাদ, মনিকা! @ বোল্ড: আমি এই প্রশ্নটি পেয়েছি, তবে এটি একটি ভিন্ন সমস্যা। জোনারশপে একটি নিখুঁত উত্তর সরবরাহ করেছেন
অফেল অফফেল

2
এটি প্রস্থের ক্রমের সাথেও সম্পর্কিত । 1 0th অর্ডার, 10 1st অর্ডার, 100 2nd আদেশ, ইত্যাদি হয়
wjandrea

উত্তর:


60

আপনি ব্যবহার করতে পারেন math.ceilসঙ্গে math.log10এই কাজ করতে:

>>> 10 ** math.ceil(math.log10(0.04))
0.1
>>> 10 ** math.ceil(math.log10(0.7))
1
>>> 10 ** math.ceil(math.log10(1.1))
10
>>> 10 ** math.ceil(math.log10(90))
100

log10(n)আপনাকে এমন সমাধান দেয় xযা সন্তুষ্ট হয় 10 ** x == n, সুতরাং আপনি যদি xএটির চারপাশ ঘটিয়ে থাকেন তবে আপনাকে পরবর্তী 10 এর সর্বোচ্চ পাওয়ারের জন্য এক্সপোনেন্ট দেয়।

মনে রাখবেন যে ইতিমধ্যে একটি পূর্ণসংখ্য nযেখানে একটি মানের জন্য x, "10 এর পরের সর্বোচ্চ শক্তি" হবে n:

>>> 10 ** math.ceil(math.log10(0.1))
0.1
>>> 10 ** math.ceil(math.log10(1))
1
>>> 10 ** math.ceil(math.log10(10))
10

1
লগ ফাংশনটির সাথে কাজ করা মনে হয় কেবল সেই কৌশলটি যা আমি সামনে আসতে পারিনি। আমি বিশ্বাস করি এটি ঠিক এটির জন্যই আমি আশা করছিলাম! অনেক অনেক ধন্যবাদ
অফেল অফফেল

2
নোট: আপনার কাঙ্ক্ষিত আচরণের উপর নির্ভর করে এটি 10 ​​টির ক্ষমতার জন্য কাজ করে না, যেমন 10 ** math.ceil(math.log10(1)) == 1, "পরবর্তী সর্বোচ্চ শক্তি" নয়
Cireo

5
দ্রষ্টব্য: এই উত্তরটি ভাসমান পয়েন্টের গাণিতিকের উপর নির্ভর করে এবং গোলাকার ত্রুটির কারণে এটি ব্যর্থ হতে পারে। উদাহরণস্বরূপ 100000000000000001 এ খাওয়ানোর চেষ্টা করুন।
প্লাগওয়াশ

2
@ প্লাগওয়াশ অগত্যা নয়, গণিত ফাংশনগুলিও যেমন ডেসিমাল গ্রহণ করবে ec ডেসিমাল।
জোনারশপে

5
হ্যাঁ আপনি অন্য ধরণের পাস করতে পারেন তবে সেগুলি ডাবল নির্ভুলতা ভাসমান পয়েন্ট সংখ্যায় রূপান্তরিত হবে এবং সি "লগ 10" ফাংশনে যাবে passed প্রচুর সংখ্যক লগগুলি উপচে পড়া রোধ করার জন্য একটি বিশেষ কেস রয়েছে, তবে গোলাকার ত্রুটিগুলি রোধ করার জন্য কিছুই নেই।
প্লাগওয়াশ

21

আপনার সমস্যাটি নীচে নির্দিষ্ট করা আছে, আপনাকে পিছনে ফিরে কিছু প্রশ্ন জিজ্ঞাসা করতে হবে।

  • আপনার ইনপুটগুলি কী ধরণের (গুলি)?
  • আপনার আউটপুটগুলির জন্য আপনি কী ধরণের (গুলি) চান?
  • 1 এরও কম ফলাফলের জন্য, আপনি ঠিক কীটি দেখতে চান? আপনি কি 10 এর প্রকৃত শক্তি চান বা 10 এর ক্ষমতার ভাসমান বিন্দুটি অনুমান করতে চান? আপনি সচেতন যে 10 এর নেতিবাচক শক্তি ঠিক ভাসমান পয়েন্টে ঠিক প্রকাশ করা যায় না? আসুন আপাতত ধরে নেওয়া যাক আপনি 10 এর ক্ষমতার ভাসমান পয়েন্টের আনুষঙ্গিকতা চান।
  • যদি ইনপুটটি হুবহু 10 এর শক্তি হয় (বা 10 এর পাওয়ারের নিকটতম ভাসমান বিন্দু অনুমান), আউটপুটটি কি ইনপুটটির মতো হওয়া উচিত? অথবা এটি 10 ​​এর পরবর্তী শক্তি হওয়া উচিত? "10 -> 10" বা "10 -> 100"? আপাতত প্রাক্তন ধরে নেওয়া যাক।
  • আপনার ইনপুট মানগুলি প্রশ্নযুক্ত ধরণের যে কোনও সম্ভাব্য মান হতে পারে? অথবা তারা আরও বাধা হয়।

অন্য উত্তরে লগারিদম নেওয়ার প্রস্তাব করা হয়েছিল, তারপরে রাউন্ড আপ (সিলিং ফাংশন), তারপরে এক্সপোনসিটিয়েট করা।

def nextpow10(n):
    return 10 ** math.ceil(math.log10(n))

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

এর ফলে এটি একটি ভুল ফলাফল দিয়েছে যেখানে একটি উদাহরণ পেতে আমার বেশি সময় লাগেনি।

>>> import math
>>> from numpy import nextafter
>>> n = 1
>>> while (10 ** math.ceil(math.log10(nextafter(n,math.inf)))) > n:
...     n *= 10
... 
>>> n
10
>>> nextafter(n,math.inf)
10.000000000000002
>>> 10 ** math.ceil(math.log10(10.000000000000002))
10

এটি অন্য দিক থেকে ব্যর্থ হওয়া তাত্ত্বিকভাবেও সম্ভব, যদিও এটি উস্কে দেওয়া আরও কঠিন বলে মনে হয়।

সুতরাং ভাসমান এবং ints এর শক্তিশালী সমাধানের জন্য আমাদের ধরে নিতে হবে যে আমাদের লোগারিদমের মান কেবল আনুমানিক, এবং তাই আমাদের অবশ্যই কয়েকটি সম্ভাবনার পরীক্ষা করতে হবে। এর লাইন বরাবর কিছু

def nextpow10(n):
    p = round(math.log10(n))
    r = 10 ** p
    if r < n:
        r = 10 ** (p+1) 
    return r;

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

দুটি বাস্তবায়ন পরীক্ষা করার জন্য আমি নিম্নলিখিত পরীক্ষার প্রোগ্রামটি ব্যবহার করেছি।

n = -323 # 10**-324 == 0
while n < 1000:
    v = 10 ** n
    if v != nextpow10(v): print(str(v)+" bad")
    try:
        v = min(nextafter(v,math.inf),v+1)
    except:
        v += 1
    if v > nextpow10(v): print(str(v)+" bad")
    n += 1

এ নিখুঁত বাস্তবায়নে প্রচুর ব্যর্থতা খুঁজে পায়, তবে উন্নত বাস্তবায়নে কোনওটিই পায় না।


এখানে আরও বিশদে যাওয়ার চেষ্টা করার জন্য আপনাকে ধন্যবাদ। যদিও জোনারশপের উত্তর ইতিমধ্যে আমার সমস্যার সমাধান করেছে, এই উত্তরটি অনুরূপ তবে আরও নির্দিষ্ট প্রশ্নযুক্ত অন্যদের জন্য কার্যকর হতে পারে।
অফেল অফফেল

1
আপনি roundপরিবর্তে ব্যবহার করবেন না কেন math.ceil? এটি r < nসত্য যেখানে প্রচুর অপ্রয়োজনীয় কেসগুলির সাথে পরিচয় করিয়ে দেবে এবং তাই এটির জন্য অতিরিক্ত কাজ করা প্রয়োজন।
a_guest

1
কারণ লগটি কোনও দিকেই বন্ধ হতে পারে।
প্লাগওয়াশ

1
কোড "উন্নত" ব্যবহার কিন্তু বৃত্তাকার কম শেষ এবং 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 উচ্চ শেষ উপর 1e-317 জন্য ব্যর্থতা math.ceil ফলাফল দ্বারা প্রতিস্থাপন করা হয়।
প্লাগওয়াশ


3

দেখে মনে হচ্ছে আপনি বরং সর্বনিম্ন পরবর্তী শক্তি চান 10 ... এখানে খাঁটি গণিত এবং লগ নয়, তবে পুনরাবৃত্তি ব্যবহার করার একটি উপায় রয়েছে।

def ceiling10(x):
    if (x > 10):
        return ceiling10(x / 10) * 10
    else:
        if (x <= 1):
            return ceiling10(10 * x) / 10
        else:
            return 10
for x in [1 / 1235, 0.5, 1, 3, 10, 125, 12345]:
    print(x, ceiling10(x))

এটি কেবল পরীক্ষা করে দেখুন, বেশিরভাগ ব্যবহারিক ক্ষেত্রে এটি ভালভাবে কাজ করে বলে মনে হচ্ছে, তবে এটি যথেষ্ট ছোট ইনপুট সহ গোলাকার ত্রুটির মধ্যে ভুগছে বলে মনে হচ্ছে। সিলিং 10 (1e-6) 1.000000000000000000ee 06 দেয়
প্লাগওয়াশ

0
y = math.ceil(x)
z = y + (10 - (y % 10))

এরকম কিছু হতে পারে? এটি আমার মাথার উপরের অংশের বাইরে কিন্তু যখন আমি টার্মিনালে কয়েকটি সংখ্যার চেষ্টা করেছি তখন এটি কাজ করেছিল।


0

এটা দেখ!

>>> i = 0.04123; print i, 10 ** len( str( int( i ) ) ) if int( i ) > 1  else 10 if i > 1.0 else 1 if i > 0.1 else  10 ** ( 1 - min( [ ("%.100f" % i ).replace('.','').index( k ) for k in [ str( j ) for j in xrange( 1, 10 ) if str( j ) in "%.100f" % i  ] ]  ) )               
0.04123 0.1
>>> i = 0.712; print i, 10 ** len( str( int( i ) ) ) if int( i ) > 1  else 10 if i > 1.0 else 1 if i > 0.1 else  10 ** ( 1 - min( [ ("%.100f" % i ).replace('.','').index( k ) for k in [ str( j ) for j in xrange( 1, 10 ) if str( j ) in "%.100f" % i  ] ]  ) )                 
0.712 1
>>> i = 1.1; print i, 10 ** len( str( int( i ) ) ) if int( i ) > 1  else 10 if i > 1.0 else 1 if i > 0.1 else  10 ** ( 1 - min( [ ("%.100f" % i ).replace('.','').index( k ) for k in [ str( j ) for j in xrange( 1, 10 ) if str( j ) in "%.100f" % i  ] ]  ) )                   
1.1 10
>>> i = 90; print i, 10 ** len( str( int( i ) ) ) if int( i ) > 1  else 10 if i > 1.0 else 1 if i > 0.1 else  10 ** ( 1 - min( [ ("%.100f" % i ).replace('.','').index( k ) for k in [ str( j ) for j in xrange( 1, 10 ) if str( j ) in "%.100f" % i  ] ]  ) )                    
90 100

দশটি পাওয়ার ইন প্রিন্সিপালের উপর ভিত্তি করে এই কোড len( str( int( float_number ) ) )

এখানে 4 টি মামলা রয়েছে:

    1. int( i ) > 1

    Floatনম্বর - রূপান্তরিত int, তারপরে স্ট্রিং str()তা থেকে আমাদের দেবেন একটি stringসঙ্গে lengthযা আমরা ঠিক খুঁজছেন। সুতরাং, প্রথম অংশ, ইনপুট জন্য i > 1.0- এটি 10এই দৈর্ঘ্যের শক্তি দশ ।

    1. এবং 3. ছোট শাখা: i > 1.0এবং i > 0.1<=> এটি যথাক্রমে 10এবং 1
    1. এবং শেষ ক্ষেত্রে, যখন i < 0.1: এখানে দশটি নেতিবাচক শক্তিতে থাকবে। কমা পরে প্রথম অ-শূন্য উপাদান পাওয়ার জন্য, আমি এই জাতীয় নির্মাণ ব্যবহার করেছি ("%.100f" % i ).replace('.','').index( k ), যেখানে k [1:10]ব্যবধানে ছুটে যায় । এরপরে, সর্বনিম্ন ফলাফলের তালিকাটি নিন। এবং এক দ্বারা হ্রাস, এটি প্রথম শূন্য, যা গণনা করা হবে। এছাড়াও, এখানে মান পাইথন এর index(), ক্র্যাশ করতে পারে যদি তা থেকে নন-জিরো উপাদান অন্তত একটি পাবে না [1:10]বিরতি হয় যে কেন শেষ আমি আবশ্যক "ফিল্টার" সংঘটন দ্বারা তালিকা: if str( j ) in "%.100f" % i। অতিরিক্তভাবে, আরও গভীরভাবে সুনির্দিষ্ট হওয়ার জন্য - পৃথকভাবে %.100fগ্রহণ করা যেতে পারে।

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