Aracılığıyla paylaş


İmzasız sağ kaydırma işleci

Not

Bu makale bir özellik belirtimidir. Belirtim, özelliğin tasarım belgesi olarak görev alır. Önerilen belirtim değişikliklerini ve özelliğin tasarımı ve geliştirilmesi sırasında gereken bilgileri içerir. Bu makaleler, önerilen belirtim değişiklikleri son haline getirilene ve geçerli ECMA belirtimine dahil edilene kadar yayımlanır.

Özellik belirtimi ile tamamlanan uygulama arasında bazı tutarsızlıklar olabilir. Bu farklılıklar,ilgili dil tasarım toplantısı (LDM) notlarında yakalanır.

Özellik belirtimlerini C# dil standardına benimseme işlemi hakkında daha fazla bilgi edinmek içinbelirtimleri makalesinde bulabilirsiniz.

Şampiyon sorunu: https://github.com/dotnet/csharplang/issues/4682

Özet

İmzasız bir sağa kaydırma işleci, C# tarafından yerleşik bir işleç (ilkel integral türleri için) ve kullanıcı tanımlı bir işleç olarak desteklenir.

Motivasyon

İmzalı tam sayı değeriyle çalışırken, bitleri sağa doğru kaydırmanız ve her kaydırmada yüksek sıralı biti çoğaltmamanız gerekebilir. Bu, normal kaydırma operatörü ile ilkel tamsayı türleri için mümkün olsa da, kaydırma işleminden önce işaretsiz bir türe dönüştürülmesi ve işlemden sonra tekrar orijinal türe dönüştürülmesi gereklidir. Kitaplıkların kullanıma sunmayı planladığı genel matematik arabirimleri bağlamında, türün genel matematik kodu tarafından önceden tanımlanmış veya bilinen imzasız bir karşıtlığa sahip olması gerekmeyebilir; oysa bir algoritma imzasız sağa kaydırma işlemi gerçekleştirme yeteneğine dayanabilir, bu da potansiyel olarak daha sorunlu hale gelebilir.

Ayrıntılı tasarım

İşleçler ve noktalama işaretleri

Bölüm §6.4.6, işaretsiz sağ shift işleci olan >>> işlecini içerecek şekilde ayarlanır:

unsigned_right_shift
    : '>>>'
    ;

unsigned_right_shift_assignment
    : '>>>='
    ;

unsigned_right_shift ve unsigned_right_shift_assignment üretimlerinde belirteçler arasında hiçbir karaktere (boşluk karakterine bile) izin verilmiyor. Bu üretimler, type_parameter_list'in doğru şekilde işlenebilmesi için özel bir şekilde ele alınır.

Shift işleçleri

Bölüm §12.11, işaretsiz sağa kaydırma operatörü >>>'yi içerecek şekilde ayarlanacaktır.

<<, >> ve >>> işleçleri, bit kaydırma işlemleri gerçekleştirmek için kullanılır.

shift_expression
    : additive_expression
    | shift_expression '<<' additive_expression
    | shift_expression right_shift additive_expression
    | shift_expression unsigned_right_shift additive_expression
    ;

Şeklindeki bir işlem için x << count veya x >> count veya x >>> count, belirli bir işleç uygulamasını seçmek amacıyla ikili işleç aşırı yükleme çözünürlüğü (§12.4.5) uygulanır. Seçilen işlecin parametre türlerine uygun olarak işlenenler dönüştürülür ve sonucun türü, işlecin dönüş türü olarak belirlenir.

Önceden tanımlanmış işaretsiz vardiya işleçleri, geçerli uygulamada önceden tanımlanmış imzalı vardiya işleçlerinin bugün desteklediği imza kümesini destekleyecektir.

  • Sağa kaydır:

    int operator >>>(int x, int count);
    uint operator >>>(uint x, int count);
    long operator >>>(long x, int count);
    ulong operator >>>(ulong x, int count);
    nint operator >>>(nint x, int count);
    nuint operator >>>(nuint x, int count);
    

    >>> işleci, x'i aşağıda açıklandığı gibi hesaplanan bir miktar bit kadar sağa kaydırır.

    x düşük sıralı bitleri atılır, kalan bitler sağa kaydırılır ve yüksek sıralı boş bit konumları sıfır olarak ayarlanır.

Önceden tanımlanmış işleçler için kaydıracak bit sayısı aşağıdaki gibi hesaplanır:

  • x türü int veya uintolduğunda, kaydırma sayısı count'ün en düşük sıradaki beş biti tarafından belirlenir. Başka bir deyişle, vardiya sayısı count & 0x1Fhesaplanır.
  • x türü long veya ulongolduğunda, vardiya sayısı alt sıralı altı bit counttarafından verilir. Başka bir deyişle, vardiya sayısı count & 0x3Fhesaplanır.

Sonuçta elde edilen vardiya sayısı sıfırsa, shift işleçleri yalnızca xdeğerini döndürür.

Shift işlemleri hiçbir zaman taşmalara neden olmaz ve checked ve unchecked bağlamlarında aynı sonuçları üretir.

Atama işleçleri

Bölüm §12.21 aşağıdaki gibi işaretsiz sağa kaydırma ataması (unsigned_right_shift_assignment) içerecek şekilde ayarlanır.

assignment_operator
    : '='
    | '+='
    | '-='
    | '*='
    | '/='
    | '%='
    | '&='
    | '|='
    | '^='
    | '<<='
    | right_shift_assignment
    | unsigned_right_shift_assignment
    ;

İntegral türleri

§8.3.6 bölümü Integral türleri, >>> işleci hakkındaki bilgileri içerecek şekilde ayarlanacaktır. İlgili madde aşağıdaki gibidir:

  • İkili <<, >> ve >>> işleçleri için, sol işlenen Ttürüne dönüştürülür; burada T, işlenenin tüm olası değerlerini tam olarak temsil edebilen int, uint, longve ulong ilkidir. İşlem daha sonra Ttürünün duyarlığı kullanılarak gerçekleştirilir ve sonucun türü ise Tşeklindedir.

Sabit ifadeler

İşleç >>>§12.23sabit ifadelerde izin verilen yapı kümesine eklenir.

İşleç aşırı yüklemesi

İşleç >>>§12.4.3konumundaki aşırı yüklenebilir ikili işleç kümesine eklenir.

Yükseltilmiş işleçler

İşleç >>>, §12.4.8konumunda yükseltilmiş bir forma izin veren ikili işleç kümesine eklenecek.

İşleç önceliği ve ilişkilendirme

Bölüm §12.4.2, "Shift" kategorisine >>> işleci ve "Atama ve lambda ifadesi" kategorisine >>>= işleci eklemek için ayarlanır.

Dil bilgisi belirsizlikleri

>>> işleci, normal bir işleci olarak >> açıklanan dil bilgisi belirsizliklerine tabidir.

Operatörler

§15.10 bölümü, >>> işlecini içerecek şekilde ayarlanır.

overloadable_binary_operator
    : '+'   | '-'   | '*'   | '/'   | '%'   | '&'   | '|'   | '^'   | '<<'
    | right_shift | unsigned_right_shift | '=='  | '!='  | '>'   | '<'   | '>='  | '<='
    ;

İkili işleçler

>>> işlecinin imzası, işlecinin imzası için >> aynı kurallara tabidir.

Meta veri adı

ECMA-335'in "I.10.3.2 İkili işleçler" bölümünde, op_UnsignedRightShift adının imzasız bir sağ kaydırma işleci için zaten ayrılmış olduğunu belirtmektedir.

Linq İfade Ağaçları

İmzalı türlerdeki önceden tanımlanmış >>> işleçlerinin semantiği, imzasız bir türe ve geriye dönüştürmeler eklemeden doğru bir şekilde temsil edilemediğinden, >>> işleci Linq İfade Ağaçlarında desteklenmez. Daha fazla bilgi için bkz. https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator.

Dinamik Bağlama

Dinamik bağlamanın, ikili işleç türünü çalışma zamanı bağlayıcısına iletmek için System.Linq.Expressions.ExpressionType sabit listesi değerlerinin kullanıldığı görülüyor. Özellikle işaretsiz bir sağa kaydırma işlecini temsil eden bir üyemiz olmadığından, >>> işleci için dinamik bağlama desteklenmez ve statik ve dinamik bağlama (§12.3) bölümü bunu yansıtacak şekilde ayarlanır.

Dezavantaj -ları

Alternatif

Linq İfade Ağaçları

>>> işleci Linq Expression Ağaçlarında desteklenecektir.

  • Kullanıcı tanımlı bir işleç için, işleç yöntemini işaret eden bir BinaryExpression düğümü oluşturulur.
  • Önceden tanımlanmış işleçler için
    • İlk işlenen imzasız bir tür olduğunda, bir BinaryExpression düğümü oluşturulur.
    • İlk işlenen işaretli bir tür olduğunda, ilk işlenen için işaretsiz bir türe dönüştürme eklenir, bir "BinaryExpression" düğümü oluşturulur ve sonuç için yeniden işaretli türe dönüştürme eklenir.

Mesela:

Expression<System.Func<int, int, int>> z = (x, y) => x >>> y; // (x, y) => Convert((Convert(x, UInt32) >> y), Int32)

Resolution:

Reddedildi, daha fazla bilgi için bkz. https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator.

Çözülmemiş sorular

Tasarım toplantıları

https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md