Bitsel kaydırma (bit kaydırma) operatörleri nedir ve nasıl çalışır?


1382

Boş zamanlarımda C öğrenmeye çalışıyordum ve diğer diller (C #, Java, vb.) Aynı konsepte sahip (ve genellikle aynı operatörler) ...

Bir çekirdek düzeyinde, ne merak ediyorum olduğunu, ne yaptığını bit değiştirme ( <<, >>, >>>) yapmak, bu çözmenize yardımcı olabilir ne sorunlar ve FRİKİKLERİNDEN viraj çevresinde pusuda ne var? Başka bir deyişle, tüm iyiliğinde biraz kaymaya yönelik mutlak bir başlangıç ​​kılavuzu.


2
3GL'lerde bit kaydırmayı kullanacağınız işlevsel veya işlevsel olmayan durumlar azdır.
Troy DeMonbreun

15
Bu yanıtları okuduktan sonra şu bağlantılara bakmak isteyebilirsiniz: graphics.stanford.edu/~seander/bithacks.html & jjj.de/bitwizardry/bitwizardrypage.html
pençeleri

1
Bit kaydırmanın bilgisayarlar için son derece kolay ve hızlı olduğunu unutmamak önemlidir. Programınızda bit kaydırmayı kullanmanın yollarını bularak, bellek kullanımını ve yürütme sürelerini önemli ölçüde azaltabilirsiniz.
Hoytman

@Hoytman: Ancak iyi derleyicilerin bu hilelerin çoğunu zaten bildiğini ve tipik olarak nerede mantıklı olduğunu fark etmede daha iyi olduğunu unutmayın.
Sebastian Mach

Yanıtlar:


1713

Bit kaydırma operatörleri tam olarak isimlerinin ne anlama geldiğini yaparlar. Bitleri kaydırıyorlar. Farklı vardiya operatörlerine kısa (veya çok kısa olmayan) bir giriş.

Operatörler

  • >> aritmetik (veya imzalı) sağ kaydırma operatörüdür.
  • >>> mantıksal (veya imzasız) sağ kaydırma operatörüdür.
  • << sola kaydırma operatörüdür ve hem mantıksal hem de aritmetik kaymaların ihtiyaçlarını karşılar.

Bu operatörlerin tüm tamsayı değerlerine uygulanabilir ( int, longmuhtemelen shortve byteya char). Bazı dillerde, vardiya operatörlerini intotomatik olarak daha küçük herhangi bir veri tipine uygulamak, işleneni bir olarak yeniden boyutlandırır int.

Bunun <<<bir operatör olmadığını unutmayın , çünkü gereksiz olur.

Ayrıca C ve C ++ 'nın sağ kaydırma operatörleri arasında ayrım yapmadığını unutmayın . Yalnızca >>operatörü sağlarlar ve sağa kayma davranışı, imzalı türler için tanımlanan bir uygulamadır. Yanıtın geri kalanı C # / Java işleçlerini kullanır.

( >>İmzalı türlerde GCC ve Clang / LLVM dahil olmak üzere tüm ana C ve C ++ uygulamalarında aritmetiktir. Bazı kodlar bunu kabul eder, ancak standart garantili bir şey değildir. Yine de tanımlanmamıştır ; standart bunu tanımlamak için uygulamalara ihtiyaç duyar Öyle ya da böyle. Ancak negatif işaretli sayının sol kaymalar olduğu (taşma tamsayı imzalanmış) tanımsız davranış. Eğer aritmetik sağa kaydırma gerek Yani sürece, bunu yapmak için iyi bir fikir genellikle var senin bit değiştirme imzasız türleri ile.)


Sola kaydırma (<<)

Tamsayılar bellekte bir dizi bit olarak saklanır. Örneğin, 32 bit olarak depolanan 6 sayısı intşöyle olur:

00000000 00000000 00000000 00000110

Bu bit desenini sola bir konuma ( 6 << 1) kaydırmak, 12 rakamıyla sonuçlanır:

00000000 00000000 00000000 00001100

Gördüğünüz gibi, rakamlar bir konum sola kaymıştır ve sağdaki son rakam sıfır ile doldurulmuştur. Ayrıca sol kaydırma 2. So yetkileri ile çarpma eşdeğerdir belirtebilir 6 << 1eşdeğerdir 6 * 2ve 6 << 3eşdeğerdir 6 * 8. İyi bir optimize edici derleyici, çarpmaların yerini mümkün olduğunda vardiyalarla değiştirecektir.

Dairesel olmayan kaydırma

Bunların dairesel vardiya olmadığını lütfen unutmayın . Bu değeri bir konum sola kaydırmak ( 3,758,096,384 << 1):

11100000 00000000 00000000 00000000

3,221,225,472 sonuç:

11000000 00000000 00000000 00000000

"Sondan" kaymış olan basamak kaybolur. Etrafına sarılmaz.


Mantıksal sağ kaydırma (>>>)

Mantıksal bir sağ kaydırma, sol kaydırmanın tersidir. Bitleri sola hareket ettirmek yerine, sadece sağa hareket ederler. Örneğin, 12 sayısını değiştirmek:

00000000 00000000 00000000 00001100

bir konum sağa ( 12 >>> 1) orijinal 6'mızı geri alır:

00000000 00000000 00000000 00000110

Bu yüzden sağa kaymanın 2 gücüne bölünmeye eşdeğer olduğunu görüyoruz.

Kayıp bitler gitti

Ancak, bir vardiya "kayıp" bitleri geri alamaz. Örneğin, bu kalıbı kaydırırsak:

00111000 00000000 00000000 00000110

sol 4 pozisyona ( 939,524,102 << 4), 2.147.483.744 elde ederiz:

10000000 00000000 00000000 01100000

ve daha sonra geri kaydırdığımızda ( (939,524,102 << 4) >>> 4) 134,217,734 elde ederiz:

00001000 00000000 00000000 00000110

Bitlerimizi kaybettikten sonra orijinal değerimizi geri alamayız.


Aritmetik sağa kaydırma (>>)

Aritmetik sağ kayma tam olarak mantıksal sağ kaymaya benzer, sıfırla doldurmak yerine en önemli bitle doldurur. Bunun nedeni, en önemli bitin işaret biti veya pozitif ve negatif sayıları ayıran bit olmasıdır. En önemli bit ile dolgu yaparak, aritmetik sağ kaydırma işaret koruyucudur.

Örneğin, bu bit desenini negatif bir sayı olarak yorumlarsak:

10000000 00000000 00000000 01100000

-2,147,483,552 numaramız var. Bunu aritmetik kayma (-2,147,483,552 >> 4) ile sağ 4 konuma kaydırmak bize şu sonuçları verecektir:

11111000 00000000 00000000 00000110

veya -134,217,722 sayısı.

Dolayısıyla, mantıksal sağ kayma yerine aritmetik sağ kaymayı kullanarak negatif sayılarımızın işaretini koruduğumuzu görüyoruz. Ve bir kez daha görüyoruz ki, 2 gücüne göre bölünme yapıyoruz.


304
Cevap, bunun Java'ya özel bir cevap olduğunu daha açık hale getirmelidir. C / C ++ veya C # 'da hiçbir >>> operatörü yoktur ve işaretin yayılıp yayılmayacağı >>, C / C ++ (büyük bir potansiyel yakalama) içinde tanımlanan bir uygulamadır
Michael Burr

56
Cevap C dili bağlamında tamamen yanlıştır. C'de "aritmetik" ve "mantıksal" kaymalara anlamlı bir bölünme yoktur. C'de kaymalar, imzalanmamış değerlerde ve pozitif işaretli değerlerde beklendiği gibi çalışır - sadece bitleri kaydırırlar. Negatif değerlerde, sağ kayma uygulama tanımlıdır (yani genel olarak ne yaptığı hakkında hiçbir şey söylenemez) ve sola kayma basitçe yasaklanmıştır - tanımlanmamış davranış üretir.
AnT

10
Audrey, kesinlikle aritmetik ve mantıksal sağa kaydırma arasında bir fark var. C, seçim uygulamasını tanımlanmış olarak bırakır. Negatif değerlerde sola kayma kesinlikle yasaktır. 0xff000000 öğesini bir bit sola kaydırın ve 0xfe000000 elde edersiniz.
Derek Park

16
A good optimizing compiler will substitute shifts for multiplications when possible. Ne? Bir CPU'nun düşük seviyeli işlemleri söz konusu olduğunda bit değişimleri daha hızlı büyüklük sıralarıdır, iyi bir optimize edici derleyici tam tersini yapar, yani iki güçle sıradan çarpmaları bit kaydırmaya dönüştürür.
Mahn

55
@ Mahn, niyetimden geriye doğru okuyorsun. X için Y ikamesi, X'i Y ile değiştirmek anlamına gelir. Y, X'in yerine geçer. Dolayısıyla, çarpma çarpmanın yerini alır.
Derek Park

209

Diyelim ki tek bir baytımız var:

0110110

Tek bir sol bit kaydırma uygulamak bize şunları sağlar:

1101100

En soldaki sıfır bayttan çıkarıldı ve baytın sağ ucuna yeni bir sıfır eklendi.

Bitler devrilmiyor; atılırlar. Bu, 1101100 vardiyasından sonra sağa kaydırdığınızda aynı sonucu geri alamayacağınız anlamına gelir.

N ile sola kaydırma, 2 N ile çarpmaya eşdeğerdir .

N ile sağa kaydırma (eğer bir tamamlayıcı kullanıyorsanız ), 2 N'ye bölme ve sıfıra yuvarlama ile eşdeğerdir .

Bitshifting, 2 gücüyle çalışmanız şartıyla delicesine hızlı çarpma ve bölme için kullanılabilir. Hemen hemen tüm düşük seviyeli grafik rutinleri bit kaydırma kullanır.

Örneğin, eski günlerde, oyunlar için 13 saat modunu (320x200 256 renk) kullandık. Mod 13h'de video belleği, piksel başına sırayla yerleştirildi. Bu, bir pikselin konumunu hesaplamak için aşağıdaki matematiği kullanırsınız:

memoryOffset = (row * 320) + column

Şimdi, o gün ve yaşta, hız kritikti, bu yüzden bu işlemi yapmak için bit değişimlerini kullanırdık.

Bununla birlikte, 320 ikisinin gücü değildir, bu yüzden bunun üstesinden gelmek için birlikte eklenen iki kişinin gücünün ne olduğunu bulmalıyız: 320:

(row * 320) = (row * 256) + (row * 64)

Şimdi bunu sol vardiyalara dönüştürebiliriz:

(row * 320) = (row << 8) + (row << 6)

Nihai sonuç için:

memoryOffset = ((row << 8) + (row << 6)) + column

Şimdi daha önce olduğu gibi aynı ofseti elde ediyoruz, pahalı bir çarpma işlemi yerine, iki bit kaydırmayı kullanıyoruz ... x86'da böyle bir şey olurdu (not, montajı yaptığımdan beri sonsuza dek oldu (editörün notu: düzeltildi) birkaç hata yaptı ve 32 bitlik bir örnek ekledi)):

mov ax, 320; 2 cycles
mul word [row]; 22 CPU Cycles
mov di,ax; 2 cycles
add di, [column]; 2 cycles
; di = [row]*320 + [column]

; 16-bit addressing mode limitations:
; [di] is a valid addressing mode, but [ax] isn't, otherwise we could skip the last mov

Toplam: Eski CPU'larda bu zamanlamaları olan 28 döngü.

VRS

mov ax, [row]; 2 cycles
mov di, ax; 2
shl ax, 6;  2
shl di, 8;  2
add di, ax; 2    (320 = 256+64)
add di, [column]; 2
; di = [row]*(256+64) + [column]

Aynı eski CPU üzerinde 12 döngü.

Evet, 16 CPU döngüsünü kapatmak için çok çalışıyoruz.

32 veya 64 bit modunda, her iki sürüm de çok daha kısa ve hızlı olur. Intel Skylake gibi modern sipariş dışı yürütme işlemcileri (bkz. Http://agner.org/optimize/ ) çok hızlı donanım çarpımına sahiptir (düşük gecikme süresi ve yüksek verim), bu nedenle kazanç çok daha küçüktür. AMD Bulldozer ailesi, özellikle 64 bit çarpma için biraz daha yavaştır. Intel CPU'larda ve AMD Ryzen'de, iki vardiya biraz daha düşük gecikme süresine sahiptir, ancak çarpmadan daha fazla talimattır (bu da daha düşük verime neden olabilir):

imul edi, [row], 320    ; 3 cycle latency from [row] being ready
add  edi, [column]      ; 1 cycle latency (from [column] and edi being ready).
; edi = [row]*(256+64) + [column],  in 4 cycles from [row] being ready.

vs.

mov edi, [row]
shl edi, 6               ; row*64.   1 cycle latency
lea edi, [edi + edi*4]   ; row*(64 + 64*4).  1 cycle latency
add edi, [column]        ; 1 cycle latency from edi and [column] both being ready
; edi = [row]*(256+64) + [column],  in 3 cycles from [row] being ready.

Derleyiciler bunu sizin için yapacak: GCC, Clang ve Microsoft Visual C ++ 'nın optimizasyon sırasında shift + lea kullandığını görünreturn 320*row + col; .

Burada dikkat edilmesi gereken en ilginç şey, x86'nınLEA küçük bir sol vardiya yapabilen ve aynı zamanda bir addtalimat olarak performansla ekleyebilen bir shift-and-add komutuna ( ) sahip olmasıdır . ARM daha da güçlü: herhangi bir talimatın bir işleyicisi sola veya sağa ücretsiz olarak kaydırılabilir. Bu nedenle, 2'nin gücü olduğu bilinen bir derleme zamanı sabitiyle ölçeklendirme, çarpma işleminden bile daha verimli olabilir.


Tamam, modern günlerde ... şimdi daha kullanışlı bir şey, 16 bitlik bir tamsayıda iki 8 bitlik değeri depolamak için bit kaydırma özelliğini kullanmak olacaktır. Örneğin, C # ile:

// Byte1: 11110000
// Byte2: 00001111

Int16 value = ((byte)(Byte1 >> 8) | Byte2));

// value = 000011111110000;

C ++ 'da, structiki 8 bit üyeli bir kullandıysanız derleyiciler bunu sizin için yapmalıdır , ancak pratikte her zaman yapmazlar.


8
Bunu genişleterek, Intel işlemcilerde (ve daha birçoğunda) bunu yapmak daha hızlıdır: int c, d; c = d << 2; Bundan daha: c = 4 * d; Bazen, "c = d << 2 + d << 1" bile "c = 6 * d" den daha hızlıdır !! Bu hileleri DOS çağındaki grafik işlevleri için yoğun olarak kullandım, artık çok kullanışlı olduklarını sanmıyorum ...
Joe Pineda

5
@James: tam olarak değil, günümüzde daha ziyade CPU yerine GPU tarafından yürütülecek olan bu tür kodu içeren video kartının bellenimi. Teorik olarak grafik fonksiyonları için böyle bir kod (veya Carmack'in kara büyü ters ters fonksiyonu gibi) uygulamanız gerekmez :-)
Joe Pineda

3
@JoePineda @james Derleyici yazarları kesinlikle onları kullanıyor. Eğer yazarsanız c=4*dbir vardiya alırsınız. Eğer yazmanız k = (n<0)da vardiya ile yapılabilir: k = (n>>31)&1bir daldan kaçınmak için. Sonuç olarak, derleyicilerin akıllılığındaki bu gelişme, şimdi bu hilelerin C kodunda kullanılmasının gereksiz olduğu ve okunabilirlik ve taşınabilirlikten ödün verdikleri anlamına geliyor. Örneğin SSE vektör kodu yazıyorsanız bunları tanımak hala çok iyidir; veya hızlı bir şekilde ihtiyacınız olan herhangi bir durum ve derleyicinin kullanmadığı bir hile var (örn. GPU kodu).
greggo

2
Diğer bir iyi bir örnektir: çok yaygın bir şey olduğu if(x >= 1 && x <= 9)gibi yapılabilir if( (unsigned)(x-1) <=(unsigned)(9-1)) büyük bir hız avantaj olabilir birine iki koşullu testleri değiştirme; özellikle de dallar yerine öngörülen uygulamaya izin verdiğinde. Bunu, 10 yıl önce derleyicilerin optimizatörde bu dönüşümü yapmaya başladığını fark edene kadar (haklı olduğu yerlerde) yıllarca kullandım, sonra durdum. Bilmeniz hala iyi, çünkü derleyicinin sizin için dönüşümü yapamadığı benzer durumlar var. Veya bir derleyici üzerinde çalışıyorsanız.
greggo

3
"Bayt" ın sadece 7 bit olmasının bir nedeni var mı?
Mason Watmough

104

Bit kaydırma dahil bitsel işlemler, düşük seviyeli donanım veya tümleşik programlama için temeldir. Bir aygıt veya hatta bazı ikili dosya biçimleri için bir belirtim okuduysanız, bayt, sözcük ve dwords ile, ilgi çekmeyen çeşitli değerler içeren bayt olmayan hizalanmış bit alanlarına bölünmüş olarak görürsünüz. Bu bit alanlarına okuma / yazma için erişmek en yaygın kullanımdır.

Grafik programlamanın basit bir gerçek örneği, 16 bitlik bir pikselin aşağıdaki gibi temsil edilmesidir:

  bit | 15| 14| 13| 12| 11| 10| 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1  | 0 |
      |       Blue        |         Green         |       Red          |

Yeşil değere ulaşmak için bunu yaparsınız:

 #define GREEN_MASK  0x7E0
 #define GREEN_OFFSET  5

 // Read green
 uint16_t green = (pixel & GREEN_MASK) >> GREEN_OFFSET;

açıklama

YALNIZCA ofset 5 ile başlayan ve 10 ile biten (yani 6 bit uzunluğunda) yeşil değerini elde etmek için, 16 bitlik pikselin tamamına uygulandığında verim verecek bir (bit) maske kullanmanız gerekir. sadece ilgilendiğimiz bitler.

#define GREEN_MASK  0x7E0

Uygun maske, ikili dosyada 0000011111100000 (ondalık olarak 2016 olan) olan 0x7E0'dır.

uint16_t green = (pixel & GREEN_MASK) ...;

Maske uygulamak için AND işlecini (&) kullanırsınız.

uint16_t green = (pixel & GREEN_MASK) >> GREEN_OFFSET;

Maskeyi uyguladıktan sonra, 16 bitlik bir sayı elde edersiniz, bu da MSB 11. bitte olduğu için gerçekten sadece 11 bitlik bir sayıdır. Yeşil aslında sadece 6 bit uzunluğundadır, bu yüzden onu doğru bir kaydırma (11 - 6 = 5) kullanarak ölçeklendirmeliyiz, dolayısıyla 5 ofset ( #define GREEN_OFFSET 5) olarak kullanılır.

Ayrıca yaygın olan, hızlı çoğaltma ve 2 güç ile bölme için bit kaydırmalarını kullanmaktır:

 i <<= x;  // i *= 2^x;
 i >>= y;  // i /= 2^y;

1
0x7e0, ondalık olarak 2016 olan 11111100000 ile aynıdır.
Saheed

50

Bit Maskeleme ve Değiştirme

Bit kaydırma genellikle düşük seviye grafik programlamada kullanılır. Örneğin, 32 bitlik bir sözcükle kodlanmış belirli bir piksel renk değeri.

 Pixel-Color Value in Hex:    B9B9B900
 Pixel-Color Value in Binary: 10111001  10111001  10111001  00000000

Daha iyi anlamak için, hangi bölümlerin hangi renk bölümünü temsil ettiği ile aynı ikili değer.

                                 Red     Green     Blue       Alpha
 Pixel-Color Value in Binary: 10111001  10111001  10111001  00000000

Diyelim ki bu pikselin renginin yeşil değerini elde etmek istiyoruz. Bu değeri maskeleyerek ve kaydırarak kolayca elde edebiliriz .

Maskemiz:

                  Red      Green      Blue      Alpha
 color :        10111001  10111001  10111001  00000000
 green_mask  :  00000000  11111111  00000000  00000000

 masked_color = color & green_mask

 masked_color:  00000000  10111001  00000000  00000000

Mantıksal &operatör yalnızca maskenin 1 olduğu değerlerin korunmasını sağlar. Şimdi yapmamız gereken son şey, tüm bu bitleri 16 yere sağa kaydırarak (tam mantıksal sağa kaydırma) doğru tamsayı değerini elde etmektir .

 green_value = masked_color >>> 16

Et voilà'da, pikselin rengindeki yeşil miktarını temsil eden bir tamsayı var:

 Pixels-Green Value in Hex:     000000B9
 Pixels-Green Value in Binary:  00000000 00000000 00000000 10111001
 Pixels-Green Value in Decimal: 185

Bu genellikle kodlama veya benzeri görüntü formatlarını çözülmesi için kullanılan jpg, pngvb


Orijinalinizi diyelim ki 32bit cl_uint'i cl_uchar4 gibi bir şey olarak yayınlamak ve doğrudan * .s2 olarak istediğiniz bayta erişmek kolay değil mi?
David H Parry

27

Bir sorun, aşağıdakilerin uygulamaya bağlı olmasıdır (ANSI standardına göre):

char x = -1;
x >> 1;

x artık 127 (01111111) veya hala -1 (11111111) olabilir.

Pratikte, genellikle ikincisidir.


4
Doğru bir şekilde hatırlarsam, ANSI C standardı bunun uygulamaya bağlı olduğunu açıkça belirtir, bu nedenle kodunuzdaki imzalı tam sayıları sağa kaydırmak istiyorsanız derleyicinizin belgelerini kontrol etmeniz gerekir.
Joe Pineda

Evet, sadece ANSI standardının kendisini vurgulamak istedim, bu yüzden satıcıların sadece standardı takip etmedikleri veya standardın bu özel durum hakkında hiçbir şey söylemediği bir durum değil.
Joe Pineda

22

Sadece ipuçları ve püf noktaları yazıyorum. Testlerde ve sınavlarda yararlı olabilir.

  1. n = n*2: n = n<<1
  2. n = n/2: n = n>>1
  3. N'nin 2'nin gücü olup olmadığını kontrol etme (1,2,4,8, ...): kontrol !(n & (n-1))
  4. Alma x inci biti n:n |= (1 << x)
  5. X'in çift mi yoksa tek mi olduğunu kontrol etme: x&1 == 0(çift)
  6. Geçiş n inci x bit:x ^ (1<<n)

Şimdiye kadar tanıdığınız birkaç tane daha olmalı?
ryyker

@ryyker Birkaç tane daha ekledim. Güncellemeye devam etmeye çalışacağım :)
Ravi Prakash

X ve n 0 indekslenmiş mi?
reggaeguitar

Reklam 5 .: Negatif bir sayı ise ne olur?
Peter Mortensen

Peki, ikilideki 2'nin ondalık 10'da olduğu sonucuna varabilir miyiz? ve bit kaydırma, ondalık sayı olarak başka bir sayının arkasına bir sayı daha eklemek veya çıkarmak gibidir.
Willy satrio nugroho

8

Java uygulamasında, kaydırılacak bit sayısının kaynağın boyutuna göre değiştirildiğini unutmayın.

Örneğin:

(long) 4 >> 65

Bitleri 65 kez sağa kaydırmak her şeyi sıfırlar, ancak aslında aşağıdakilere eşdeğerdir:

(long) 4 >> (65 % 64)

Bu <<, >> ve >>> için geçerlidir. Diğer dillerde denemedim.


Hah, ilginç! C'de bu teknik olarak tanımlanmamış bir davranıştır . gcc 5.4.0bir uyarı verir, ancak 25 >> 65; de.
pizzapants184

2

Python'da bazı yararlı bit işlemleri / manipülasyonları.

Ravi Prakash'ın cevabını Python'a uyguladım .

# Basic bit operations
# Integer to binary
print(bin(10))

# Binary to integer
print(int('1010', 2))

# Multiplying x with 2 .... x**2 == x << 1
print(200 << 1)

# Dividing x with 2 .... x/2 == x >> 1
print(200 >> 1)

# Modulo x with 2 .... x % 2 == x & 1
if 20 & 1 == 0:
    print("20 is a even number")

# Check if n is power of 2: check !(n & (n-1))
print(not(33 & (33-1)))

# Getting xth bit of n: (n >> x) & 1
print((10 >> 2) & 1) # Bin of 10 == 1010 and second bit is 0

# Toggle nth bit of x : x^(1 << n)
# take bin(10) == 1010 and toggling second bit in bin(10) we get 1110 === bin(14)
print(10^(1 << 2))

-3

Windows platformunda yalnızca PHP'nin 32 bit sürümünün bulunduğunu unutmayın.

Örneğin, << veya >> değerini 31 bitten fazla kaydırırsanız, sonuçlar beklenmedik olur. Genellikle sıfırlar yerine orijinal sayı döndürülür ve gerçekten zor bir hata olabilir.

Tabii ki PHP'nin 64 bit sürümünü (Unix) kullanıyorsanız, 63 bitten fazla kaydırmaktan kaçınmalısınız. Ancak, örneğin, MySQL 64 bit BIGINT kullanır, bu nedenle uyumluluk problemleri olmamalıdır.

GÜNCELLEME: PHP 7 Windows'dan, PHP derlemeleri nihayet tam 64 bit tamsayıları kullanabilir: Tamsayı boyutu platforma bağlıdır, ancak maksimum iki milyarlık değer normal değerdir (32 bit imzalı). 64-bit platformlar, PHP 7'den önceki Windows dışında, her zaman 32 bit olduğu için genellikle maksimum 9E18 değerine sahiptir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.