IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

F# Discussion :

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


Sujet :

F#

  1. #1
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    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# : Sélectionner tout - Visualiser dans une fenêtre à part
    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# : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    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 chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    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# : Sélectionner tout - Visualiser dans une fenêtre à part
    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# : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 990
    Points
    2 990
    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: mon projet, 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 expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    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 chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    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.

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/06/2014, 10h34
  2. \textwidth différent selon le type tableau,minipage,etc.
    Par pinpom dans le forum Mise en forme
    Réponses: 9
    Dernier message: 02/12/2011, 13h43
  3. Réponses: 12
    Dernier message: 22/11/2010, 16h33
  4. Réponses: 0
    Dernier message: 25/02/2009, 08h51
  5. [RegEx] Résultat différent selon le mode d'exécution de PHP
    Par mgauffeny dans le forum Langage
    Réponses: 2
    Dernier message: 30/07/2008, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo