<< ve >> operatörlerine gidin


124

Biri bana lütfen Go'nun <<ve >>Go'nun kullanımını açıklayabilir mi? Sanırım diğer bazı dillere benziyor.

Yanıtlar:


169

Süper (muhtemelen aşırı) basitleştirilmiş tanım sadece <<"çarpı 2" için kullanılır ve "2'ye >>bölünmesi" için kullanılır - ve ondan sonraki sayı kaç kezdir.

Yani n << xbir "n kere 2, x kere". Ve y >> z"y bölü 2, z çarpı" dır.

Örneğin 1 << 5, "1 kere 2, 5 kere" veya 32'dir. Ve 32 >> 5"32 bölü 2, 5 kere" veya 1'dir.

Diğer tüm cevaplar daha teknik bir tanım veriyor, ama kimse bunu açıkça ortaya koymadı ve bunu isteyebileceğinizi düşündüm.


7
Bu harika bir cevap. Bu gerçekten kafamda sağlamlaştırdı, teşekkürler.
Sam Orozco

2
Cevaplar böyle olmalı.
Utsav Gupta

103

En spec itibaren http://golang.org/doc/go_spec.html , tamsayılar ile en azından bir ikili vardiya gibi görünüyor. örneğin, ikili 0b00001000 >> 1, 0b00000100 ve 0b00001000 << 1, 0b00010000 olacaktır.


Görünüşe göre Go, ikili tam sayılar için 0b gösterimini kabul etmiyor. Ben sadece örnek için kullanıyordum. Ondalık olarak, 8 >> 1 4'tür ve 8 << 1 16'dır. Bir sola kaydırmak, 2 ile çarpmakla aynıdır ve sağa kaydırmak ikiye bölmekle, kalanı atarak aynıdır.


4
Mükemmel cevap. Bunu, 2'nin (1 << güç = 2 ^ güç) kodlarında gördüğümü düşündüğümde çok mantıklı geliyor
Stephen Smith,

6
Bence bu tam denklem: (x << n == x * 2 ^ n) (x >> n == x * 2 ^ (- n))
MondayPaper

güzel cevap, ben ilk bakışta ikili değişiklik yapmak zahmetli göründü ama değeri 2'ye kadar ondalık
sayıya çevirmek

31

<< ve >> operatörleri Go Aritmetik Operatörleri'dir .

<<   left shift             integer << unsigned integer
>>   right shift            integer >> unsigned integer

Kaydırma operatörleri, sol işleneni sağ işlenen tarafından belirtilen kaydırma sayısı kadar kaydırır. Sol işlenen işaretli bir tamsayı ise aritmetik kaydırma ve işaretsiz bir tamsayı ise mantıksal kaydırma uygularlar. Vardiya sayısı, işaretsiz bir tam sayı olmalıdır. Vardiya sayısında üst sınır yoktur. Kaydırmalar, sol işlenen n kez kaydırma sayısı için 1 kaydırılmış gibi davranır. Sonuç olarak, x << 1, x * 2 ile aynıdır ve x >> 1, x / 2 ile aynıdır, ancak negatif sonsuza doğru kesilmiştir.


10

Bunlar temelde Aritmetik operatörlerdir ve diğer dillerde de aynısı temel bir PHP, C, Go Örneği

GİT

package main

import (
    "fmt"
)

func main() {
    var t , i uint
    t , i = 1 , 1

    for i = 1 ; i < 10 ; i++ {
        fmt.Printf("%d << %d = %d \n", t , i , t<<i)
    }


    fmt.Println()

    t = 512
    for i = 1 ; i < 10 ; i++ {
        fmt.Printf("%d >> %d = %d \n", t , i , t>>i)
    }

}

Demoya git

C

#include <stdio.h>
int main()
{

    int t = 1 ;
    int i = 1 ;

    for(i = 1; i < 10; i++) {
        printf("%d << %d = %d \n", t, i, t << i);
    }

        printf("\n");

    t = 512;

    for(i = 1; i < 10; i++) {
        printf("%d >> %d = %d \n", t, i, t >> i);
    }    

  return 0;
}

C Demo

PHP

$t = $i = 1;

for($i = 1; $i < 10; $i++) {
    printf("%d << %d = %d \n", $t, $i, $t << $i);
}

print PHP_EOL;

$t = 512;

for($i = 1; $i < 10; $i++) {
    printf("%d >> %d = %d \n", $t, $i, $t >> $i);
}

PHP Demosu

Hepsi çıktı

1 << 1 = 2 
1 << 2 = 4 
1 << 3 = 8 
1 << 4 = 16 
1 << 5 = 32 
1 << 6 = 64 
1 << 7 = 128 
1 << 8 = 256 
1 << 9 = 512 

512 >> 1 = 256 
512 >> 2 = 128 
512 >> 3 = 64 
512 >> 4 = 32 
512 >> 5 = 16 
512 >> 6 = 8 
512 >> 7 = 4 
512 >> 8 = 2 
512 >> 9 = 1 

7

Go'nun << ve >> diğer dillerdeki vardiyalara (yani: 2 kuvvetiyle bölme veya çarpma) benzer, ancak Go, C / C ++ 'dan daha güvenli bir dil olduğu için vardiya sayısı bir sayı olduğunda bazı ekstra işler yapar .

X86 CPU'lardaki kaydırma talimatları, kaydırma sayısının yalnızca 5 bitini (64 bit x86 CPU'larda 6 bit) dikkate alır. C / C ++ gibi dillerde, vardiya operatörü tek bir CPU talimatına çevrilir.

Aşağıdaki Go kodu

x := 10
y := uint(1025)  // A big shift count
println(x >> y)
println(x << y)

baskılar

0
0

bir C / C ++ programı yazdırırken

5
20

3
C ve C ++ kaydırma operatörleri için, "Sağ işlenen negatifse veya yükseltilen sol işlenenin bit cinsinden uzunluğundan büyük veya bu uzunluğa eşitse davranış tanımsızdır." C ve C ++ standartları, C ve C ++ programlarının 5 ve 20'yi yazdıracağını garanti etmez.
peterSO

@peterSO: Evet, haklısın. Benim bakış açım, her programlama dili standardının somut bir CPU üzerinde somut bir uygulamaya sahip olması gerektiğidir. Tek bir CPU ailesi (x86-32) bağlamında, tüm C / C ++ derleyicilerinin davranışı aynıdır (olması beklenebilir). Bunun nedeni, kaydırma operatörünü uygulamak için tam olarak 1 SHL / SHR / etc komutunu yaymanın, bağlam 'x' ve 'y' hakkında hiçbir şey söylemediğinde optimize eden bir C / C ++ derleyicisinin yapabileceği en iyi şeydir. Ve derleyici kodun tanımsız davranışa sahip olduğunu bilirse, kullanıcıyı bu konuda bilgilendirmelidir.

2
Katılmıyorum. Taşınabilir kod yazmalısınız. Hem Linux hem de Windows ARM üzerinde çalışır. Tek bir CPU ailesine odaklanmak dar görüşlüdür. Ayrıca y bir değişkendir. Bir gerçek için, derleyicinin gerçek çalışma zamanı değerleri hakkında hiçbir bilgisi yoktur.
peterSO

@Atom Neler olacağına dair kesinlikle hiçbir garanti sağlamayan dilin yanı sıra, örneğin derleme seçeneklerini değiştirirseniz (örneğin optimize edilmiş bir yapı), tanımlanmamış davranış, tek bir derleyiciye sahip tek bir makinede bile değişebilir. Herhangi bir şekilde ona güvenmek tehlikeli derecede yanlış IMO.
Paul Hankin

@Anonymous Evet, ancak bu sadece teori. Derleme seçeneklerinin değiştirilmesinin , C / C ++ ' <<ya veya >>C

6

<<sol vardiyadır. >>sol işlenen işaretli bir tamsayı olduğunda işaret genişleten sağa kaydırmadır ve sol işlenen işaretsiz bir tamsayı olduğunda sıfır genişleyen sağa kaydırmadır.

Daha iyi anlamak için >>düşün

var u uint32 = 0x80000000;
var i int32 = -2;

u >> 1;  // Is 0x40000000 similar to >>> in Java
i >> 1;  // Is -1 similar to >> in Java

Dolayısıyla, işaretsiz bir tamsayıya uygulandığında, soldaki bitler sıfırla doldurulurken, işaretli bir tam sayıya uygulandığında, soldaki bitler en soldaki bit ile doldurulur (işaretli tam sayı, 2'ye göre negatif olduğunda 1'dir) Tamamlayıcı).


3

Gelen ondalık matematik , biz ne zaman çarpma veya bölme 10 oranında , biz numarasının ucunda sıfır etkisi.

In ikili , 2 aynı etkiye sahiptir. Bu yüzden sonuna sıfır ekliyoruz veya son basamağı kaldırıyoruz

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.