পাইথনে, আপনি পূর্ণসংখ্যায় অঙ্কের সংখ্যাটি কীভাবে খুঁজে পাবেন?
পাইথনে, আপনি পূর্ণসংখ্যায় অঙ্কের সংখ্যাটি কীভাবে খুঁজে পাবেন?
উত্তর:
আপনি যদি পূর্ণসংখ্যার অঙ্কের সংখ্যার মতো কোনও পূর্ণসংখ্যার দৈর্ঘ্য চান, আপনি সর্বদা এটির স্ট্রিংয়ে রূপান্তর করতে str(133)
এবং এর দৈর্ঘ্যের মতো সন্ধান করতে পারেন len(str(123))
।
Math.log10
পদ্ধতিটি গ্রহণ করেছে মাত্র 7.486343383789062e-05 সেকেন্ড, প্রায় 1501388 গুণ দ্রুত!
Math.log10
পরিবর্তে ব্যবহার করুন।
স্ট্রিংতে রূপান্তর ছাড়াই
import math
digits = int(math.log10(n))+1
শূন্য এবং নেতিবাচক সংখ্যাগুলিও পরিচালনা করতে
import math
if n > 0:
digits = int(math.log10(n))+1
elif n == 0:
digits = 1
else:
digits = int(math.log10(-n))+2 # +1 if you don't count the '-'
আপনি সম্ভবত এটি কোনও ফাংশনে রাখতে চাইবেন :)
এখানে কিছু মানদণ্ড দেওয়া হল। len(str())
এমনকি বেশ ছোট সংখ্যার জন্য পিছনে আগে থেকেই
timeit math.log10(2**8)
1000000 loops, best of 3: 746 ns per loop
timeit len(str(2**8))
1000000 loops, best of 3: 1.1 µs per loop
timeit math.log10(2**100)
1000000 loops, best of 3: 775 ns per loop
timeit len(str(2**100))
100000 loops, best of 3: 3.2 µs per loop
timeit math.log10(2**10000)
1000000 loops, best of 3: 844 ns per loop
timeit len(str(2**10000))
100 loops, best of 3: 10.3 ms per loop
int(math.log10(x)) +1
জন্য 99999999999999999999999999999999999999999999999999999999999999999999999
( 71 নবম সংখ্যা ) ফেরৎ 72 ? আমি ভেবেছিলাম যে আমি লগ 10 পদ্ধতিতে নির্ভর করতে পারি তবে এর পরিবর্তে আমাকে লেন (স্ট্র (এক্স)) ব্যবহার করতে হবে :(
math.log10(999999999999999)
সমান 14.999999999999998
তাই int(math.log10(999999999999999))
হয় 14
। তবে math.log10(9999999999999999)
তার সমান 16.0
। হতে পারে ব্যবহার round
করা এই সমস্যার সমাধান।
math.log10 দ্রুত তবে সমস্যাটি দেয় যখন আপনার সংখ্যা 999999999999997 এর চেয়ে বেশি হয়। কারণ ভাসমানটির পরিমাণ অনেক বেশি s
সমাধানটি হ'ল এই প্রান্তিকের উপরের সংখ্যার জন্য একটি সময়ের কাউন্টার পদ্ধতি ব্যবহার করা।
এটি আরও দ্রুততর করার জন্য, 10 ^ 16, 10 create 17 তৈরি করে নিন এবং তালিকায় ভেরিয়েবল হিসাবে সঞ্চয় করুন। এইভাবে, এটি একটি টেবিল দেখার মতো।
def getIntegerPlaces(theNumber):
if theNumber <= 999999999999997:
return int(math.log10(theNumber)) + 1
else:
counter = 15
while theNumber >= 10**counter:
counter += 1
return counter
math.log10
। বাইনারি উপস্থাপনাগুলি কীভাবে গাণিতিকভাবে ভুল ফলাফল দেয় তার মানগুলি কীভাবে ফ্লপ করে তা দেখতে আকর্ষণীয়।
পাইথন 2.*
int
আপনার পাইথন বিল্ডের উপর নির্ভর করে 4 বা 8 বাইট (32 বা 64 বিট) নিতে পারেন। sys.maxint
( 2**31-1
৩২-বিট ইনটসের 2**63-1
জন্য , -৪-বিট ইনটগুলির জন্য) আপনাকে দু'টি সম্ভাবনার মধ্যে কোনটি প্রাপ্ত বলে দেবে।
পাইথন 3-তে, int
( long
পাইথন 2 এর মতো ) উপলব্ধ মেমরির পরিমাণ পর্যন্ত নির্বিচারে আকার নিতে পারে; sys.getsizeof
আপনাকে কোনও নির্দিষ্ট মানের জন্য একটি ভাল ইঙ্গিত দেয়, যদিও এটি কিছু স্থির ওভারহেডও গণনা করে :
>>> import sys
>>> sys.getsizeof(0)
12
>>> sys.getsizeof(2**99)
28
যদি অন্য উত্তরগুলি সূচিত করে, আপনি পূর্ণসংখ্যার মানটির কয়েকটি স্ট্রিং উপস্থাপনের কথা ভাবছেন, তবে len
সেই উপস্থাপনাটি কেবল গ্রহণ করুন , এটি বেস 10 বা অন্যথায় হউক!
এই প্রশ্নটি জিজ্ঞাসা করার পরে বেশ কয়েক বছর হয়েছে, তবে আমি পূর্ণসংখ্যার দৈর্ঘ্য গণনা করার জন্য কয়েকটি পদ্ধতির একটি মানদণ্ড সংকলন করেছি।
def libc_size(i):
return libc.snprintf(buf, 100, c_char_p(b'%i'), i) # equivalent to `return snprintf(buf, 100, "%i", i);`
def str_size(i):
return len(str(i)) # Length of `i` as a string
def math_size(i):
return 1 + math.floor(math.log10(i)) # 1 + floor of log10 of i
def exp_size(i):
return int("{:.5e}".format(i).split("e")[1]) + 1 # e.g. `1e10` -> `10` + 1 -> 11
def mod_size(i):
return len("%i" % i) # Uses string modulo instead of str(i)
def fmt_size(i):
return len("{0}".format(i)) # Same as above but str.format
(libc ফাংশনটির জন্য কিছু সেটআপ প্রয়োজন যা আমি অন্তর্ভুক্ত করি না)
size_exp
ব্রায়ান প্রেসলপস্কির size_str
কাছে ধন্যবাদ , ধন্যবাদ গীকতন্ত্রকে, এবংsize_math
জানায় এবং জন লা ধন্যবাদ জানায়
ফলাফল এখানে:
Time for libc size: 1.2204 μs
Time for string size: 309.41 ns
Time for math size: 329.54 ns
Time for exp size: 1.4902 μs
Time for mod size: 249.36 ns
Time for fmt size: 336.63 ns
In order of speed (fastest first):
+ mod_size (1.000000x)
+ str_size (1.240835x)
+ math_size (1.321577x)
+ fmt_size (1.350007x)
+ libc_size (4.894290x)
+ exp_size (5.976219x)
(অস্বীকৃতি: ফাংশনটি ইনপুটগুলিতে 1 থেকে 1,000,000 পর্যন্ত চালিত হয়)
এখানে জন্য ফলাফল নেই sys.maxsize - 100000
করার sys.maxsize
:
Time for libc size: 1.4686 μs
Time for string size: 395.76 ns
Time for math size: 485.94 ns
Time for exp size: 1.6826 μs
Time for mod size: 364.25 ns
Time for fmt size: 453.06 ns
In order of speed (fastest first):
+ mod_size (1.000000x)
+ str_size (1.086498x)
+ fmt_size (1.243817x)
+ math_size (1.334066x)
+ libc_size (4.031780x)
+ exp_size (4.619188x)
যেমন আপনি দেখতে পাচ্ছেন, mod_size
( len("%i" % i)
) হ'ল দ্রুত, ব্যবহারের চেয়ে সামান্য দ্রুত str(i)
এবং অন্যের তুলনায় উল্লেখযোগ্য দ্রুত।
libc = ctyle.CDLL('libc.so.6', use_errno=True)
(এটি অনুমান করা এটি এটি)। এবং এটি এর চেয়ে বেশি সংখ্যার জন্য কাজ করে না sys.maxsize
কারণ ভাসমান পয়েন্ট সংখ্যাগুলি "খুব বড়" হতে পারে না। সুতরাং উপরের যে কোনও সংখ্যা, আমি অনুমান করি আপনি একটি ধীর পদ্ধতির সাথে আটকে আছেন।
সংখ্যাটি তার n
পরে সংখ্যাটির সংখ্যাটি n
দেওয়া হোক:
math.floor(math.log10(n))+1
নোট করুন যে এটি + ve পূর্ণসংখ্যার <10e15- এর জন্য সঠিক উত্তর দেবে। এর বাইরে ফিরে আসা প্রকারের math.log10
কিকের যথার্থ সীমাবদ্ধতা এবং উত্তরটি 1 দিয়ে বন্ধ হতে পারে I আমি কেবল এর len(str(n))
বাইরে ব্যবহার করব ; এটি প্রয়োজনO(log(n))
সময় যা 10 এর ক্ষমতার উপরে পুনরাবৃত্তি হওয়ার সমান।
এই সীমাবদ্ধতাটিতে আমার মনোনিবেশ আনার জন্য @ সিটিভোলকিল্যানিকে ধন্যবাদ জানাই। এটি আশ্চর্যজনক কীভাবে আপাতদৃষ্টিতে সঠিক সমাধানগুলি প্রয়োগের বিশদগুলিতে সতর্কতা অবলম্বন করে।
assert list(range(1,51)) == [math.floor(math.log10(n))+1 for n in (10**e for e in range(50))]
।
>>> math.floor(math.log10(999999999999997))+1 15.0 >>> math.floor(math.log10(999999999999998))+1 16.0
। আমার উত্তর দেখুন stackoverflow.com/a/42736085/6003870 ।
সংখ্যাকে ডাব্লু / ও এর সংখ্যাকে একটি স্ট্রিংয়ে রূপান্তর করুন:
x=123
x=abs(x)
i = 0
while x >= 10**i:
i +=1
# i is the number of digits
প্রিয় ব্যবহারকারী @ ক্যালভিন্টউউর হিসাবে উল্লিখিত হিসাবে, ফাংশনটির math.log10
[-99999999999999997, 999999999999997]] এর বাইরে কিছু সংখ্যক ক্ষেত্রে সমস্যা রয়েছে, যেখানে আমরা ভাসমান পয়েন্ট ত্রুটি পাই। আমি জাভাস্ক্রিপ্ট (গুগল ভি 8 এবং নোডজেএস) এবং সি (জিএনইউ জিসিসি সংকলক) নিয়ে এই সমস্যাটি পেয়েছিলাম, সুতরাং 'purely mathematically'
এখানে একটি সমাধান অসম্ভব।
এই উপর ভিত্তি করে সারকথা এবং উত্তর দুর্মূল্য ব্যবহারকারী @Calvintwr
import math
def get_count_digits(number: int):
"""Return number of digits in a number."""
if number == 0:
return 1
number = abs(number)
if number <= 999999999999997:
return math.floor(math.log10(number)) + 1
count = 0
while number:
count += 1
number //= 10
return count
আমি 20 (সমেত) পর্যন্ত দৈর্ঘ্যের সংখ্যায় এটি পরীক্ষা করেছি এবং ঠিক আছে। এটি অবশ্যই পর্যাপ্ত হতে হবে, কারণ 64-বিট সিস্টেমে দৈর্ঘ্য সর্বাধিক পূর্ণসংখ্যার সংখ্যা 19 ( len(str(sys.maxsize)) == 19
)।
assert get_count_digits(-99999999999999999999) == 20
assert get_count_digits(-10000000000000000000) == 20
assert get_count_digits(-9999999999999999999) == 19
assert get_count_digits(-1000000000000000000) == 19
assert get_count_digits(-999999999999999999) == 18
assert get_count_digits(-100000000000000000) == 18
assert get_count_digits(-99999999999999999) == 17
assert get_count_digits(-10000000000000000) == 17
assert get_count_digits(-9999999999999999) == 16
assert get_count_digits(-1000000000000000) == 16
assert get_count_digits(-999999999999999) == 15
assert get_count_digits(-100000000000000) == 15
assert get_count_digits(-99999999999999) == 14
assert get_count_digits(-10000000000000) == 14
assert get_count_digits(-9999999999999) == 13
assert get_count_digits(-1000000000000) == 13
assert get_count_digits(-999999999999) == 12
assert get_count_digits(-100000000000) == 12
assert get_count_digits(-99999999999) == 11
assert get_count_digits(-10000000000) == 11
assert get_count_digits(-9999999999) == 10
assert get_count_digits(-1000000000) == 10
assert get_count_digits(-999999999) == 9
assert get_count_digits(-100000000) == 9
assert get_count_digits(-99999999) == 8
assert get_count_digits(-10000000) == 8
assert get_count_digits(-9999999) == 7
assert get_count_digits(-1000000) == 7
assert get_count_digits(-999999) == 6
assert get_count_digits(-100000) == 6
assert get_count_digits(-99999) == 5
assert get_count_digits(-10000) == 5
assert get_count_digits(-9999) == 4
assert get_count_digits(-1000) == 4
assert get_count_digits(-999) == 3
assert get_count_digits(-100) == 3
assert get_count_digits(-99) == 2
assert get_count_digits(-10) == 2
assert get_count_digits(-9) == 1
assert get_count_digits(-1) == 1
assert get_count_digits(0) == 1
assert get_count_digits(1) == 1
assert get_count_digits(9) == 1
assert get_count_digits(10) == 2
assert get_count_digits(99) == 2
assert get_count_digits(100) == 3
assert get_count_digits(999) == 3
assert get_count_digits(1000) == 4
assert get_count_digits(9999) == 4
assert get_count_digits(10000) == 5
assert get_count_digits(99999) == 5
assert get_count_digits(100000) == 6
assert get_count_digits(999999) == 6
assert get_count_digits(1000000) == 7
assert get_count_digits(9999999) == 7
assert get_count_digits(10000000) == 8
assert get_count_digits(99999999) == 8
assert get_count_digits(100000000) == 9
assert get_count_digits(999999999) == 9
assert get_count_digits(1000000000) == 10
assert get_count_digits(9999999999) == 10
assert get_count_digits(10000000000) == 11
assert get_count_digits(99999999999) == 11
assert get_count_digits(100000000000) == 12
assert get_count_digits(999999999999) == 12
assert get_count_digits(1000000000000) == 13
assert get_count_digits(9999999999999) == 13
assert get_count_digits(10000000000000) == 14
assert get_count_digits(99999999999999) == 14
assert get_count_digits(100000000000000) == 15
assert get_count_digits(999999999999999) == 15
assert get_count_digits(1000000000000000) == 16
assert get_count_digits(9999999999999999) == 16
assert get_count_digits(10000000000000000) == 17
assert get_count_digits(99999999999999999) == 17
assert get_count_digits(100000000000000000) == 18
assert get_count_digits(999999999999999999) == 18
assert get_count_digits(1000000000000000000) == 19
assert get_count_digits(9999999999999999999) == 19
assert get_count_digits(10000000000000000000) == 20
assert get_count_digits(99999999999999999999) == 20
পাইথন 3.5 এর সাথে পরীক্ষিত কোডগুলির সমস্ত উদাহরণ
উত্তরোত্তর জন্য, এই সমস্যার দীর্ঘতমতম সমাধান নিঃসন্দেহে:
def num_digits(num, number_of_calls=1):
"Returns the number of digits of an integer num."
if num == 0 or num == -1:
return 1 if number_of_calls == 1 else 0
else:
return 1 + num_digits(num/10, number_of_calls+1)
from math import log10
digits = lambda n: ((n==0) and 1) or int(log10(abs(n)))+1
ধরে নেওয়া যাক যে আপনি সবচেয়ে বড় সংখ্যার জন্য জিজ্ঞাসা করছেন যা আপনি পূর্ণসংখ্যায় সঞ্চয় করতে পারেন, মানটি বাস্তবায়ন নির্ভর। আমি পরামর্শ দিচ্ছি যে অজগরটি ব্যবহার করার সময় আপনি সেভাবে ভাবেন না। যাই হোক না কেন, বেশ বড় মান একটি অজগর 'পূর্ণসংখ্যায়' সংরক্ষণ করা যেতে পারে। মনে রাখবেন, পাইথন হাঁসের টাইপিং ব্যবহার করে!
সম্পাদনা: আমি স্পষ্টির আগে আমার উত্তর দিয়েছিলাম যে প্রশ্নকর্তা অঙ্কের সংখ্যা চান? তার জন্য, আমি গৃহীত উত্তর দ্বারা প্রস্তাবিত পদ্ধতির সাথে একমত। যোগ করার মতো আর কিছুই না!
def length(i):
return len(str(i))
এটি ব্যবহার করে দ্রুত পূর্ণসংখ্যার জন্য করা যেতে পারে:
len(str(abs(1234567890)))
যা "1234567890" এর পরম মানের স্ট্রিংয়ের দৈর্ঘ্য পায়
abs
কোনও negativeণাত্মক (সংখ্যাটির মাত্রা) ছাড়াই নম্বরটি প্রদান করে, str
এটিকে স্ট্রিং-এ রূপান্তর করে এবংlen
স্ট্রিংয়ের দৈর্ঘ্য দেয়।
যদি আপনি এটি ভাসমানদের জন্য কাজ করতে চান তবে আপনি নিম্নলিখিত দুটি ব্যবহার করতে পারেন:
# Ignore all after decimal place
len(str(abs(0.1234567890)).split(".")[0])
# Ignore just the decimal place
len(str(abs(0.1234567890)))-1
ভবিষ্যতের রেফারেন্সের জন্য।
int
এটির দশমিক স্ট্রিং প্রতিনিধিত্ব কেটে দেওয়ার চেয়ে ইনপুট নম্বরটি নিজেই কাটা (যেমন একটি কাস্ট সহ ) কেটে নেওয়া সহজ হবে : len(str(abs(int(0.1234567890))))
1 টি রিটার্ন দেয়
বৈজ্ঞানিক স্বরলিপিতে ফর্ম্যাট করুন এবং ঘাতককে তাড়িয়ে দিন:
int("{:.5e}".format(1000000).split("e")[1]) + 1
আমি গতি সম্পর্কে জানি না, তবে এটি সহজ।
দয়া করে নোট করুন দশমিকের পরে উল্লেখযোগ্য সংখ্যার সংখ্যা (".5e" "" 5 "" যদি এটি বৈজ্ঞানিক স্বরলিপিটির দশমিক অংশটিকে অন্য অঙ্কে সীমাবদ্ধ করে তোলে তবে এটি একটি ইস্যু হতে পারে I আপনি জানেন এমন বৃহত্তম সংখ্যার দৈর্ঘ্য।
def count_digit(number):
if number >= 10:
count = 2
else:
count = 1
while number//10 > 9:
count += 1
number = number//10
return count
যদি আপনাকে কোনও ব্যবহারকারীকে ইনপুট দিতে বলতে হয় এবং তারপরে আপনাকে কত নম্বর রয়েছে তা গণনা করতে হবে তবে আপনি এটি অনুসরণ করতে পারেন:
count_number = input('Please enter a number\t')
print(len(count_number))
দ্রষ্টব্য: ব্যবহারকারীর ইনপুট হিসাবে কখনই গ্রহণ করবেন না।
def digits(n)
count = 0
if n == 0:
return 1
while (n >= 10**count):
count += 1
n += n%10
return count
print(digits(25)) # Should print 2
print(digits(144)) # Should print 3
print(digits(1000)) # Should print 4
print(digits(0)) # Should print 1
এর জন্য আমার কোডটি নীচে রয়েছে; আমি লগ 10 পদ্ধতিটি ব্যবহার করেছি:
from math import *
ডিফ ডিজিট_কাউন্ট (সংখ্যা):
if number>1 and round(log10(number))>=log10(number) and number%10!=0 :
return round(log10(number))
elif number>1 and round(log10(number))<log10(number) and number%10!=0:
return round(log10(number))+1
elif number%10==0 and number!=0:
return int(log10(number)+1)
elif number==1 or number==0:
return 1
আমাকে 1 এবং 0 এর ক্ষেত্রে উল্লেখ করতে হয়েছিল কারণ লগ 10 (1) = 0 এবং লগ 10 (0) = এনডি এবং সুতরাং উল্লিখিত শর্তটি সন্তুষ্ট নয়। তবে এই কোডটি কেবল পুরো সংখ্যার জন্যই কাজ করে।
এখানে একটি বিশাল কিন্তু দ্রুত সংস্করণ রয়েছে:
def nbdigit ( x ):
if x >= 10000000000000000 : # 17 -
return len( str( x ))
if x < 100000000 : # 1 - 8
if x < 10000 : # 1 - 4
if x < 100 : return (x >= 10)+1
else : return (x >= 1000)+3
else: # 5 - 8
if x < 1000000 : return (x >= 100000)+5
else : return (x >= 10000000)+7
else: # 9 - 16
if x < 1000000000000 : # 9 - 12
if x < 10000000000 : return (x >= 1000000000)+9
else : return (x >= 100000000000)+11
else: # 13 - 16
if x < 100000000000000 : return (x >= 10000000000000)+13
else : return (x >= 1000000000000000)+15
খুব বেশি সংখ্যক নয় বলে কেবল 5 টি তুলনা। আমার কম্পিউটারে এটি math.log10
সংস্করণ থেকে প্রায় 30% দ্রুত এবং len( str())
একটির চেয়ে 5% দ্রুত । ঠিক আছে ... আপনি যদি উগ্রভাবে ব্যবহার না করেন তবে এত আকর্ষণীয় নয়।
এবং এখানে আমার ফাংশনটি পরীক্ষা / পরিমাপ করতে ব্যবহৃত সংখ্যার সেটটি দেওয়া হয়েছে:
n = [ int( (i+1)**( 17/7. )) for i in xrange( 1000000 )] + [0,10**16-1,10**16,10**16+1]
এনবি: এটি নেতিবাচক সংখ্যা পরিচালনা করে না, তবে অভিযোজন সহজ ...
>>> a=12345
>>> a.__str__().__len__()
5
len(str(a))
।