Dengan Python, bagaimana Anda menemukan jumlah digit dalam bilangan bulat?
Jika Anda ingin panjang bilangan bulat seperti dalam jumlah digit dalam bilangan bulat, Anda selalu dapat mengonversinya menjadi string seperti str(133) dan menemukan panjangnya seperti len(str(123)).
Tanpa konversi ke string
import math digits = int(math.log10(n))+1Untuk juga menangani angka nol dan negatif
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 '-'Anda mungkin ingin menempatkan itu dalam suatu fungsi :)
Inilah beberapa tolok ukur. len(str()) sudah ada di belakang bahkan untuk jumlah yang sangat kecil
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 loopSemua solusi math.log10 akan memberi Anda masalah.
math.log10 cepat tetapi memberikan masalah ketika nomor Anda lebih besar dari 999999999999997. Ini karena float memiliki terlalu banyak .9s, menyebabkan hasil untuk mengumpulkan.
Solusinya adalah menggunakan metode penghitung sementara untuk angka di atas ambang batas itu.
Untuk menjadikan ini lebih cepat, buat 10 ^ 16, 10 ^ 17 seterusnya dan simpan sebagai variabel dalam daftar. Dengan begitu, ini seperti pencarian tabel.
def getIntegerPlaces(theNumber): if theNumber <= 999999999999997: return int(math.log10(theNumber)) + 1 else: counter = 15 while theNumber >= 10**counter: counter += 1 return counterPython 2.*ints membutuhkan 4 atau 8 byte (32 atau 64 bit), tergantung pada build Python Anda. sys.maxint (2**31-1 untuk int 32-bit, 2**63-1 untuk ints 64-bit) akan memberi tahu Anda yang mana dari dua kemungkinan yang diperoleh.
Dalam Python 3, ints (seperti longs dalam Python 2) dapat mengambil ukuran sewenang-wenang hingga jumlah memori yang tersedia; sys.getsizeof memberi Anda indikasi yang baik untuk setiap nilai yang diberikan, meskipun tidak juga menghitung beberapa overhead tetap:
>>> import sys >>> sys.getsizeof(0) 12 >>> sys.getsizeof(2**99) 28Jika, seperti jawaban lain menyarankan, Anda berpikir tentang beberapa representasi string dari nilai integer, maka ambil len dari representasi itu, baik itu di basis 10 atau sebaliknya!
Biarkan n maka jumlah digit n diberikan oleh:
math.floor(math.log10(n))+1Perhatikan bahwa ini akan memberikan jawaban yang benar untuk + ve integer <10e15. Di luar batas ketepatan jenis kembalinya math.log10 tendangan masuk dan jawabannya mungkin tidak aktif oleh 1. Saya hanya akan menggunakan len(str(n)) di luar itu; ini membutuhkan waktu O(log(n)) yang sama dengan iterasi dari kekuatan 10.
Terima kasih kepada @SetiVolkylany karena telah membawa perhatian saya ke batasan ini. Sungguh menakjubkan betapa solusi yang tampaknya benar memiliki peringatan dalam detail implementasi.
Nah, tanpa mengkonversi ke string saya akan melakukan sesuatu seperti:
def lenDigits(x): """ Assumes int(x) """ x = abs(x) if x < 10: return 1 return 1 + lenDigits(x / 10)Rekursi Minimalis FTW
Seperti yang disebutkan pengguna sayang @Calvintwr, fungsi math.log10 memiliki masalah dalam sejumlah di luar kisaran [-999999999999997, 999999999999997], di mana kita mendapatkan kesalahan titik apung. Saya punya masalah dengan JavaScript (Google V8 dan NodeJS) dan C (kompiler GCC GNU, jadi solusi 'purely mathematically' tidak mungkin ada di sini.
Berdasarkan Gist dan answer pengguna yang terhormat ini @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 countSaya mengujinya pada angka dengan panjang hingga 20 (inklusif) dan baik-baik saja. Itu harus cukup, karena angka integer panjang maks pada sistem 64-bit adalah 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) == 20Semua contoh kode diuji dengan Python 3.5
Untuk anak cucu, tidak diragukan lagi sejauh ini solusi paling lambat untuk masalah ini:
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)Sudah beberapa tahun sejak pertanyaan ini diajukan, tetapi saya telah menyusun tolok ukur beberapa metode untuk menghitung panjang bilangan bulat.
def size_libc(i): return libc.snprintf(buf, 100, c_char_p(b'%i'), i) # equivalent to `return snprintf(buf, 100, "%i", i);` def size_str(i): return len(str(i)) # Length of `i` as a string def size_math(i): return 1 + math.floor(math.log10(i)) # 1 + floor of log10 of i def size_exp(i): return int("{:.5e}".format(i).split("e")[1]) + 1 # e.g. `1e10` -> `10` + 1 -> 11 def size_mod(i): return len("%i" % i) # Uses string modulo instead of str(i) def size_fmt(i): return len("{0}".format(i)) # Same as above but str.format(fungsi libc memerlukan beberapa pengaturan, yang belum saya sertakan)
size_exp berkat Brian Preslopsky, size_str berkat GeekTantra, dan size_math berkat John La Rooy
Inilah hasilnya:
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)(Penafian: fungsi dijalankan pada input 1 hingga 1.000.000)
Berikut adalah hasil untuk sys.maxsize - 100000 hingga 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)Seperti yang Anda lihat, mod_size (len("%i" % i)) adalah yang tercepat, sedikit lebih cepat daripada menggunakan str(i) dan secara signifikan lebih cepat daripada yang lain.
from math import log10 digits = lambda n: ((n==0) and 1) or int(log10(abs(n)))+1
Ini dapat dilakukan untuk bilangan bulat dengan cepat dengan menggunakan:
len(str(abs(1234567890)))Yang mendapatkan panjang string dari nilai absolut "1234567890"
abs mengembalikan nomor TANPA negatif (hanya besarnya angka), str melemparkan/mengubahnya menjadi string dan len mengembalikan panjang string dari string itu.
Jika Anda ingin itu berfungsi untuk float, Anda dapat menggunakan salah satu dari berikut ini:
# Ignore all after decimal place len(str(abs(0.1234567890)).split(".")[0]) # Ignore just the decimal place len(str(abs(0.1234567890)))-1Untuk referensi di masa mendatang.
def length(i): return len(str(i))
Dengan asumsi Anda meminta angka terbesar yang dapat Anda simpan dalam bilangan bulat, nilainya tergantung pada implementasi. Saya menyarankan agar Anda tidak berpikir seperti itu ketika menggunakan python. Bagaimanapun, nilai yang cukup besar dapat disimpan dalam 'integer' python. Ingat, Python menggunakan mengetik bebek!
Edit: Saya memberikan jawaban sebelum klarifikasi bahwa penanya menginginkan jumlah digit. Untuk itu, saya setuju dengan metode yang disarankan oleh jawaban yang diterima. Tidak ada lagi yang ditambahkan!
Format dalam notasi ilmiah dan cabut eksponen:
int("{:.5e}".format(1000000).split("e")[1]) + 1Saya tidak tahu tentang kecepatan, tapi itu sederhana.
Harap perhatikan jumlah digit signifikan setelah desimal ("5" di ".5e" dapat menjadi masalah jika itu membulatkan bagian desimal dari notasi ilmiah ke angka lain. Saya menetapkannya secara besar-besaran, tetapi dapat mencerminkan panjang jumlah terbesar yang Anda ketahui.
Hitung jumlah digit tanpa konversi bilangan bulat ke string:
x=123 x=abs(x) i = 0 while x >= 10**i: i +=1 # i is the number of digits