SORU
14 Aralık 2009, PAZARTESİ


C/C standart işareti bir fonksiyon () signum, sgn var mı ?

Negatif sayılar için -1 döndüren bir işlev istiyorum ve pozitif sayılar için 1. http://en.wikipedia.org/wiki/Sign_function Kolay yeterince yazdım, ama bu standart bir kütüphane bir yerde olması gereken bir şey gibi görünüyor.

Edit: Özellikle, bir işlevi yüzer çalışma arıyordum.

CEVAP
5 Ocak 2011, ÇARŞAMBA


Kimse şubesiz yazmamış şaşırdım, tip-güvenli C sürüm:

template <typename T> int sgn(T val) {
    return (T(0) < val) - (val < T(0));
}

Faydaları:

  • Aslında uygular signum (-1, 0 veya 1). Uygulamaları burada copysign sadece dönüş kullanarak -1 ya da signum olan 1,. Ayrıca, bazı uygulamaları burada bir yüzer (T) savurgan gibi bir int yerine dönüyor.
  • Değer vermez, yüzer, iki katına çıkar, imzasız şort veya herhangi özel bir tür için çalışır tamsayı 0 ve hiç gelen constructible.
  • Hızlı! copysign özellikle etmek gerekir, ve daha dar, daha sonra ise yavaş. Bu şubesiz ve optimize mükemmel
  • Standartlarla uyumlu! Hack düzgün, ama sadece bitshift bazı bit gösterimleri için çalışır, ve işaretsiz bir tür olduğunda çalışmıyor. Uygun zaman manuel bir uzmanlık olarak da sağlanabilir.
  • Doğru! Sıfır ile basit karşılaştırmalar makine yüksek hassasiyetli iç temsil (x 87 örneğin 80 bit) korumak ve erken bir yuvarlak önlemek sıfır.

Uyarılar:

  • Derlemek için sonsuza kadar sürecek bir şablon.
  • Görünüşe göre bazı insanlar yeni, biraz ezoterik ve çok yavaş standart bir kütüphane işlevinin kullanımı düşünüyorumo bile gerçekten signum uygulamak değildaha anlaşılabilir.
  • Onay < 0 bölümü GCC -Wtype-limits işaretsiz bir tür örneği uyarı tetikler. Bazı aşırı kullanarak bunu önleyebilirsiniz:

    template <typename T> inline constexpr
    int signum(T x, std::false_type is_signed) {
        return T(0) < x;
    }
    
    template <typename T> inline constexpr
    int signum(T x, std::true_type is_signed) {
        return (T(0) < x) - (x < T(0));
    }
    
    template <typename T> inline constexpr
    int signum(T x) {
        return signum(x, std::is_signed<T>());
    }
    

    İlk uyarı. iyi bir örnek)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • kndx

    kndx

    11 Mart 2006
  • mliskIT

    mliskIT

    29 Mart 2012
  • WestsideMrArO

    WestsideMrAr

    6 EKİM 2010