Précédent   Forum du club des développeurs et IT Pro > Autres langages > Langages fonctionnels > F#
F# Forum d'entraide sur la programmation en langage fonctionnel F#
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 22/08/2010, 03h57   #1
Sehnsucht
Membre Expert
 
Avatar de Sehnsucht
 
Homme Mickaël
Développeur .NET
Inscription : octobre 2008
Messages : 487
Détails du profil
Informations personnelles :
Nom : Homme Mickaël
Âge : 29
Localisation : France, Lot et Garonne (Aquitaine)

Informations professionnelles :
Activité : Développeur .NET

Informations forums :
Inscription : octobre 2008
Messages : 487
Points : 1 023
Points : 1 023
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à:
Citation:
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 ?
Sehnsucht est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2010, 13h20   #2
gorgonite
Rédacteur/Modérateur

 
Avatar de gorgonite
 
Homme Nicolas Vallée
Ingénieur d'études
Inscription : décembre 2005
Messages : 9 961
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Vallée
Âge : 28
Localisation : France

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

Informations forums :
Inscription : décembre 2005
Messages : 9 961
Points : 18 152
Points : 18 152
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
gorgonite est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2010, 13h56   #3
Sehnsucht
Membre Expert
 
Avatar de Sehnsucht
 
Homme Mickaël
Développeur .NET
Inscription : octobre 2008
Messages : 487
Détails du profil
Informations personnelles :
Nom : Homme Mickaël
Âge : 29
Localisation : France, Lot et Garonne (Aquitaine)

Informations professionnelles :
Activité : Développeur .NET

Informations forums :
Inscription : octobre 2008
Messages : 487
Points : 1 023
Points : 1 023
@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 ?
Sehnsucht est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2010, 14h03   #4
SpiceGuid
Rédacteur
 
Avatar de SpiceGuid
 
Homme Damien Guichard
Inscription : juin 2007
Messages : 1 512
Détails du profil
Informations personnelles :
Nom : Homme Damien Guichard
Localisation : France, Loire (Rhône Alpes)

Informations forums :
Inscription : juin 2007
Messages : 1 512
Points : 2 495
Points : 2 495
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 projet, le blog dvp et le jeu vidéo.
Avant de poser une question je lis les règles du forum.
SpiceGuid est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2010, 14h16   #5
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 962
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 962
Points : 1 148
Points : 1 148
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.

Citation:
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).
LLB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2010, 14h54   #6
Sehnsucht
Membre Expert
 
Avatar de Sehnsucht
 
Homme Mickaël
Développeur .NET
Inscription : octobre 2008
Messages : 487
Détails du profil
Informations personnelles :
Nom : Homme Mickaël
Âge : 29
Localisation : France, Lot et Garonne (Aquitaine)

Informations professionnelles :
Activité : Développeur .NET

Informations forums :
Inscription : octobre 2008
Messages : 487
Points : 1 023
Points : 1 023
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 ?
Sehnsucht est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 15h17.


 
 
 
 
Partenaires

Hébergement Web