Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 6 sur 6
  1. #1
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro Mickaël
    Développeur .NET
    Inscrit en
    octobre 2008
    Messages
    529
    Détails du profil
    Informations personnelles :
    Nom : Homme Mickaël
    Âge : 31
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : octobre 2008
    Messages : 529
    Points : 1 181
    Points
    1 181

    Par défaut Petite incompréhension -> résultat différent selon le type

    Bonjour,

    Déjà je viens à peine de découvrir F# (et les langages fonctionnels par la même occasion), donc j'y vais lentement, j'essaie de bien tout comprendre (c'est pas gagné ) et pour cela je me sers du Project Euler pour me faire la main.

    En fait j'ai un souci concernant ce problème là:
    2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

    What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
    j'ai tout d'abord écrit ce code là (après maints essais )
    Code F# :
    1
    2
    3
    4
    5
    let Euler005 =
        let rec pgcd x y = if y = 0 then x else pgcd y ( x % y )
        let ppcm x y = x * y / ( pgcd x y )
        { 1 .. 20 } |> Seq.fold ppcm 1
    Qui m'a affiché comme résultat 18 044 195 qui ne se trouve pas être la bonne réponse.
    Après m'être relu, avoir griffonné sur papier, et ne pas m'être rendu compte d'une erreur flagrante, j'ai bidouillé ça un peu dans tout les sens pour arriver à force de changements (et d'annulation de changements) à ceci
    Code F# :
    1
    2
    3
    4
    5
    let Euler005 =
        let rec pgcd x y = if y = 0L then x else pgcd y ( x % y )
        let ppcm x y = x * y / ( pgcd x y )
        { 1L .. 20L } |> Seq.fold ppcm 1L
    Notez que la seule différence est le typage passé de int à int64 et là je lance et pof 232 792 560 le bon résultat

    Alors je fais un bon :yeah: mais au final je pige pas pourquoi ça donne le bon résultat avec des int64 et pas avec des int vu que je suis à peine à 10% de la valeur maximale pour un int

    Donc si quelqu'un peut m'éclairer là dessus (ou sur mon algo, un conseil est toujours bon à prendre ) je le remercie d'avance.

    Cordialement !
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )

    À quelle heure dormez-vous ?

    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  2. #2
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro Nicolas Vallée
    Ingénieur d'études
    Inscrit en
    décembre 2005
    Messages
    10 206
    Détails du profil
    Informations personnelles :
    Nom : Homme Nicolas Vallée
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : décembre 2005
    Messages : 10 206
    Points : 16 754
    Points
    16 754

    Par défaut

    ce n'est pas la valeur du résultat, mais celle du plus grand entier utilisé dans les calculs qui importe
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  3. #3
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro Mickaël
    Développeur .NET
    Inscrit en
    octobre 2008
    Messages
    529
    Détails du profil
    Informations personnelles :
    Nom : Homme Mickaël
    Âge : 31
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : octobre 2008
    Messages : 529
    Points : 1 181
    Points
    1 181

    Par défaut

    @gorgonite

    Un grand merci à toi, j'aurais pu la chercher longtemps celle-là ; ça m'aura appris un truc en plus, ne pas se focaliser que sur le résultat final

    au final j'ai pu me rendre compte de ce dont tu parlais en modifiant mon code comme ceci
    Code F# :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    let Euler005 =
        let rec pgcd x y = if y = 0L then x else pgcd y ( x % y )
        let ppcm x y =
            if ( x * y ) > int64( System.Int32.MaxValue ) then
                printfn "%d" ( x * y ) |> ignore
            x * y / ( pgcd x y )
        { 1L .. 20L } |> Seq.fold ppcm 1L
    ;;
    
    //Output :
    //4655851200
    //val e5 : int64 = 232792560L
    Ce qui m'amène à une question subsidiaire ; comprenant que c'était la multiplication qui causait le dépassement j'ai ensuite ré-écris comme ceci :
    Code F# :
    1
    2
    3
    4
    5
    6
    7
    8
    let Euler005 =
        let rec pgcd x y = if y = 0 then x else pgcd y ( x % y )
        let ppcm x y = x / (pgcd x y) * y
        { 1 .. 20 } |> Seq.fold ppcm 1
    
    //Output :
    //val e5 : int = 232792560
    En changeant l'ordre des opérations plus de dépassement donc ça marche avec des int, mais y en a-t-il une à préférer que l'autre (dans ce cas seulement ou le cas général ?) et bien sûr si possible pourquoi ?

    Question bonus: J'ai vu dans ce post Page code source, mettez vos sources ici ! que SpiceGuid avait la coloration en postant, sauf que quand je mets CODE=F# j'ai rien, j'imagine donc qu'il a fait autrement... mais comment au juste ?

    Cordialement !
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )

    À quelle heure dormez-vous ?

    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  4. #4
    Rédacteur
    Avatar de SpiceGuid
    Homme Profil pro Damien Guichard
    Inscrit en
    juin 2007
    Messages
    1 574
    Détails du profil
    Informations personnelles :
    Nom : Homme Damien Guichard
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : juin 2007
    Messages : 1 574
    Points : 2 449
    Points
    2 449

    Par défaut

    Désolé, il n'y a pas de coloration lexicale pour ocaml/F#.
    Ce que j'utilise c'est un script qui ajoute une balise color sur chaque mot-clé ocaml.
    Du même auteur: le cours OCaml, le dernier article publié, le blog dvp et le jeu vidéo.
    Avant de poser une question je lis les règles du forum.

  5. #5
    LLB
    LLB est déconnecté
    Membre Expert
    Inscrit en
    mars 2002
    Messages
    962
    Détails du profil
    Informations forums :
    Inscription : mars 2002
    Messages : 962
    Points : 1 128
    Points
    1 128

    Par défaut

    Sehnsucht : tu peux aussi mettre "open Checked" au début de ton code. Dès qu'il y aura un dépassement lors d'une opération mathématique, tu auras une exception.

    En changeant l'ordre des opérations plus de dépassement donc ça marche avec des int, mais y en a-t-il une à préférer que l'autre (dans ce cas seulement ou le cas général ?) et bien sûr si possible pourquoi ?
    Le résultat ne sera pas toujours le même, puisque c'est une division entière (tu ignores un éventuel reste). Ici, ça marche pour des raisons mathématiques (x est multiple de son pgcd), mais tu pourrais avoir des surprises dans d'autres cas (4 / 5 * 3 = 0).

  6. #6
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro Mickaël
    Développeur .NET
    Inscrit en
    octobre 2008
    Messages
    529
    Détails du profil
    Informations personnelles :
    Nom : Homme Mickaël
    Âge : 31
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : octobre 2008
    Messages : 529
    Points : 1 181
    Points
    1 181

    Par défaut

    Citation Envoyé par SpiceGuid Voir le message
    Désolé, il n'y a pas de coloration lexicale pour ocaml/F#.
    Ce que j'utilise c'est un script qui ajoute une balise color sur chaque mot-clé ocaml.
    Bon ben tant pis, le noir c'est tendance aussi

    Citation Envoyé par LLB Voir le message
    Sehnsucht : tu peux aussi mettre "open Checked" au début de ton code. Dès qu'il y aura un dépassement lors d'une opération mathématique, tu auras une exception.

    Le résultat ne sera pas toujours le même, puisque c'est une division entière (tu ignores un éventuel reste). Ici, ça marche pour des raisons mathématiques (x est multiple de son pgcd), mais tu pourrais avoir des surprises dans d'autres cas (4 / 5 * 3 = 0).
    Je ne connaissais pas "open Checked" j'en suis encore à la découverte, et à essayer de faire comprendre à mon cerveau impératif la logique fonctionnelle

    Bon je place le sujet en Résolu, merci à tous

    Cordialement
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )

    À quelle heure dormez-vous ?

    Censément, quelqu'un de sensé est censé s'exprimer sensément.

+ Répondre à la discussion
Cette discussion est résolue.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •