[Résolu][Swift] Priorité des opérateurs.

PyrohPyroh Membre
avril 2016 modifié dans Objective-C, Swift, C, C++ #1

Ouais c'est vague comme titre, désolé (si après avoir lu quelqu'un en a un meilleur à  proposer je prends)


 


J'ai créé un type CGAngle qui modélise un angle sur un cercle (donc [0, 360[ only). Les angles négatifs sont transformés en leur complément positif (e.g -60° devient 300°).


Par défault CGAngle a une valeur en rad. Donc:



let a1: CGAngle = M_PI
let a2 = CGAngle(degree: 180)

a1 == a2 // TRUE

Comme j'avais pas envie de me taper un CGAngle(degree.... à  chaque fois (qui cause en radians, hein ? Je veux des noms) j'ai créé un opérateur postixé °. Ce qui fait que:



let a3: CGAngle = M_PI
let a4 = 180° // CGAngle inferred from ° operator

a3 == a4 // TRUE

Pour avoir une vraie valeur numérique CGAngle a une propriété native (comme CGFloat, ouais c'est du plagiat) de type CGFloat. 


 


Ce qui nous amène à  notre problème (le miens surtout) :



​CGAngle(degree: 60) == 60° // TRUE
CGAngle(degree: -60) == -60° // TRUE  
CGAngle(degree: 60).native == 60°.native // TRUE
CGAngle(degree: -60).native == -60°.native // FALSE  

On dirait qu'au lieu de faire ((-60)°).native il fait plutôt -((60°).native).


 


Est-ce normal ou non ? Si oui pourquoi ce changement de priorité dans les opérateurs ?


Réponses

  • Qu'est ce qui te fait dire qu'il y a un changement de priorité des opérateurs ?




  • (qui cause en radians, hein ? Je veux des noms)




    Tous les profs de math de la planète et les scientifiques.



  • Qu'est ce qui te fait dire qu'il y a un changement de priorité des opérateurs ?




     


    -60° applique l'opérateur - au literal 60 puis applique l'opérateur ° au résultat.


    -60°.native applique l'opérateur ° au literal 60 puis applique l'opérateur - à  la propriété native du résultat.


     


    Pourquoi l'opérateur préfixé passe alors en dernier dans le second cas alors qu'il passait en premier dans l'autre cas ?


     




    Tous les profs de math de la planète et les scientifiques.




    Ah oui, eux... Tu oublie cependant de préciser qu'ils s'expriment surtout en fraction de pi.

  • As tu créer un opérateur prefix - pour ta classe (structure ?) CAngle ?



  • As tu créer un opérateur prefix - pour ta classe (structure ?) CAngle ?




    Oui et il fait correctement le boulot.


    Mais dans le cas de -60°.native c'est pas l'opérateur prefix - de CGAngle qui est en cause mais celui de CGFloat. Vu que la propriété native est de type CGFloat.

  • Ça y est j'ai compris je suis un âne.

    Les opérateur postfixés ont une plus grande priorité que les opérateurs préfixés.

    Donc dans -60° l'opérateur - est appliqué au résultat de 60° et logiquement ° est appliqué au literal 60.

     

    Je vais relire la doc, ça me parait pas logique (peut-être que ça l'est on est si on par du principe que je suis un âne...)




  •  


    Ah oui, eux... Tu oublie cependant de préciser qu'ils s'expriment surtout en fraction de pi.




    Par définition, les radians sont des fractions de pi .. Un cercle complet = 2*pi radians.

  • Joanna CarterJoanna Carter Membre, Modérateur
    avril 2016 modifié #9

    Pyroh


     


    Petite expérimentation :



    public struct CGAngle
    {
    public var radians: Double

    public var degrees: Double
    {
    return radians * 180 / M_PI
    }

    public init(_ radians: Double)
    {
    self.radians = (radians < 0.0 ? radians + 2 * M_PI : radians) % (2 * M_PI)
    }

    public init(degrees: Double)
    {
    self.init(degrees * M_PI / 180)
    }
    }


    postfix operator ° {}

    public postfix func °(angle: CGAngle) -> Double
    {
    return angle.degrees
    }

    public postfix func °(angle: Double) -> CGAngle
    {
    return CGAngle(degrees: angle)
    }

    public prefix func -(angle: CGAngle) -> CGAngle
    {
    return CGAngle(-(angle.radians))
    }

    public prefix func -(angle: Double) -> CGAngle
    {
    return CGAngle(-angle)
    }

    public func +(left: CGAngle, right: CGAngle) -> CGAngle
    {
    return CGAngle(left.radians + right.radians)
    }

    public func +=(inout left: CGAngle, right: CGAngle)
    {
    left = CGAngle(left.radians + right.radians)
    }

    public func -(left: CGAngle, right: CGAngle) -> CGAngle
    {
    return CGAngle(left.radians - right.radians)
    }

    public func -=(inout left: CGAngle, right: CGAngle)
    {
    left = CGAngle(left.radians - right.radians)
    }

    public func == (left: CGAngle, right: CGAngle) -> Bool
    {
    return left.radians == right.radians
    }

    Code de test



    print(CGAngle(degrees: 60.0) == 60.0°) // TRUE
    print(CGAngle(degrees: -60.0) == -60.0°) // TRUE
    print(CGAngle(degrees: 60.0).radians == 60.0°.radians) // TRUE
    print(CGAngle(degrees: -60.0).radians == (-60.0)°.radians) // TRUE


    var angle = 60°

    angle += 70°

    print(angle°)
  • Oui Joanna c'est peu ou prou ce que j'ai fait.


    Je me demande un peu pourquoi les opérateurs postfixés sont prioritaires sur les opérateurs préfixés... J'ai rien trouvé dans la doc.


  • Vraiment une bonne idée ton opérateur ° postfixé. C'est impressionnant de lisibilité dans un source. J'adore.



  • Vraiment une bonne idée ton opérateur ° postfixé. C'est impressionnant de lisibilité dans un source. J'adore.




    Ouais j'ai trouvé aussi que c'était une bonne idée  ^_^

Connectez-vous ou Inscrivez-vous pour répondre.