Apakah integer pada python memiliki batasan panjang atau besaran?

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))+1

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

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

Python 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)
28

Jika, 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))+1

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

Saya 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) == 20

Semua 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)))-1

Untuk 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]) + 1

Saya 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

Apa itu integer pada Python?

Tipe data integer adalah tipe data numerik yang menampung bilangan bulat. Contohnya bilangan 1,2,3 dan seterusnya. Sehingga setiap variabel yang memiliki nilai bilangan bulat, maka ia akan dikategorikan sebagai integer. Dalam bahasa Python, panjang dari data integer dibatasi oleh besarnya memori yang tersedia.

Apa itu string dan integer Python?

String merupakan tipe untuk objek berupa teks (kata/kalimat). Untuk objek yang berupa angka, digunakan tipe integer dan float. Integer untuk objek bilangan bulat baik positif maupun negatif, sedangkan float untuk objek bilangan desimal positif dan negatif.

Apa perbedaan string dan integer?

String dalam pemrograman komputer adalah sebuah deret simbol. Tipe data string adalah tipe data yang di gunakan untuk menyimpan barisan karakter. integer untuk merujuk kepada tipe data apapun yang merepresentasikan bilangan bulat, atau beberapa bagian dari bilangan bulat, di sebut juga sebagai lntegral Data Type.

Apakah penggunaan tipe data integer pada Python akan memerlukan tanda kutip dua?

Sedangkan untuk angka (integer) dan boolean tidak perlu diapit dengan tanda petik.