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

Caml Discussion :

Utiliser le type Num


Sujet :

Caml

  1. #1
    Membre à l'essai
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Points : 10
    Points
    10
    Par défaut Utiliser le type Num
    Bonjour,

    Voilà j'ai un petit souci avec ce type de données (plus d'info ici : http://caml.inria.fr/pub/docs/manual...ibref/Num.html), j'aimerais simplement faire une division de 2 entiers et en sortir un nombre décimal très grand.
    Mon exemple : 103993 / 33102, qui doit donner une approximation de pi.
    En caml, ça me donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    #load "nums.cma";;
    open Num;;
     
    (*Version 1 :*)
    Int 103993 // Int 33102;;
    (*Résultat*)
    - : Num.num = Ratio <abstr>
     
    (*Version 2 :*)
    let printnum n = print_string (string_of_num n);;
    #install_printer printnum;;
    let n = Int 103993 // Int 33102;;
    printnum n;;
    (*Résultat*)
    103993/33102- : unit = ()
    Si je remplace mon "//" par une addition (+/), une multiplication (*/) ou une soustraction (-/), j'ai un résultat qui s'affiche correctement et tout va bien dans les 2 cas.
    Mais pour la division, rien à faire.
    Quelqu'un a une solution pour ma simple division ?

  2. #2
    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
    Citation Envoyé par AlexiZ
    j'aimerais simplement faire une division de 2 entiers et en sortir un nombre décimal très grand.
    Le résultat de Num.(//) est un nombre rationnel c'est-à-dire ∈ ℚ.

    Si tu veux calculer dans ℕ il faut utiliser le module Big_int.

    PI en goutte-à-goutte (exact, temps ∞) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #load "nums.cma";;
    let add  = Big_int.add_big_int
    and sub  = Big_int.sub_big_int
    and succ = Big_int.succ_big_int
    and pred = Big_int.pred_big_int
    and mult = Big_int.mult_big_int
    and div  = Big_int.div_big_int
    and add_int  = Big_int.add_int_big_int
    and mult_int = Big_int.mult_int_big_int
    and big_int  = Big_int.big_int_of_int
    and int_of   = Big_int.int_of_big_int
    ;;
    let pi () =
      let rec g q r t i =
        let i3 = mult_int 3 i in
        let u = mult_int 3 (mult (add_int 1 i3) (add_int 2 i3))
        and y = int_of (div (add (mult q (add_int (-12) (mult_int 27 i))) (mult_int 5 r)) (mult_int 5 t)) 
        in begin
          print_int y;
          flush stdout;
          g
          (mult_int 10 (mult q (mult i (add_int (-1) (mult_int 2 i)))))
          (mult_int 10 (mult u (sub (add (mult q (add_int (-2) (mult_int 5 i))) r) (mult_int y t))))
          (mult t u)
          (add_int 1 i);
          ()
        end
      in g (big_int 1) (big_int 180) (big_int 60) (big_int 2);; 
    
    pi ();;
    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.

  3. #3
    Membre à l'essai
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Points : 10
    Points
    10
    Par défaut
    Merci d'avoir répondu.

    L'objectif n'est pas de cacluler dans ℕ mais bien dans ℚ. Est-ce que c'est possible ?
    La méthode du goutte à goutte donne bien un nombre important de décimales mais je ne comprends pas vraiment comment cela fonctionne, une précision sur les paramètres de g ?

  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
    Citation Envoyé par AlexiZ Voir le message
    L'objectif n'est pas de cacluler dans ℕ mais bien dans ℚ. Est-ce que c'est possible ?
    Oui, c'est possible en utilisant le module Num.

    Citation Envoyé par AlexiZ Voir le message
    une précision sur les paramètres de g ?
    http://web.comlab.ox.ac.uk/oucl/work...ons/spigot.pdf
    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
    Membre à l'essai
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par SpiceGuid Voir le message
    Oui, c'est possible en utilisant Num.(//)
    ça va pas être simple
    Mais en tout cas merci, je vais voir avec tout ça pour trouver quelque chose de probant.
    Juste une dernière question en passant, je ne peux pas utiliser "power_num" sans avoir une "Exception : invalid argument power_num", une idée ?

  6. #6
    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
    Citation Envoyé par AlexiZ Voir le message
    L'objectif n'est pas de cacluler dans ℕ mais bien dans ℚ. Est-ce que c'est possible ?
    Ne reviens pas demain pour nous dire qu'en fait tu veux calculer ∏ dans ℝ
    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.

  7. #7
    Membre à l'essai
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par SpiceGuid Voir le message
    Ne reviens pas demain pour nous dire qu'en fait tu veux calculer ∏ dans ℝ
    Parce que ça change quelque chose à mon problème ?
    Ne rentrons pas dans les détails mathématiques je ne suis qu'informaticien ^^

    Rien pour mon power sinon ? Je suis en train de la redéfinir, pas d'autre choix pour l'instant.

  8. #8
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Bonjour, <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Num.html#VALapprox_num_exp" target="_blank">Num.approx_num_exp</a> n'est-il pas ce qu'il te faut ?

    Et je pense qu'il veut calculer dans .
    -- Yankel Scialom

  9. #9
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Ha ! Et pour power :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    # Num.string_of_num (Num.power_num (Num.Int 504) (Num.Int 378)) ;;
    - : string =
    "33017392796145806168337542681632713604222995935988104123216879182928287894637048840597359552449336745902720910544576973376130276949945491709905194218388383927856494067568803810302723077080946938739059037654665557394630501724251429824678985000638923778108694450062077564482084416549777079249340604967521869646485255276241847131673592534722055015732764520610641645335086861421489622712513199518845994268387656780995195534217937542957200585918221068910253052292848581363845925365716402627687039286067310038747591656793390292631073518412591070311243669118312872835834456483469330329157209133904610082236915275558489487488920630490252596041569445152487024145367571764359878632171319807038019819019452538149624144276074228441991563894798422713706949206950320068915073838271807637016504830677150339287105118769260883601878681028320754504596371742050877247059336773795088839280844064430752831753633722391538027607060217484414866980566718815985992891941408840128305692064276730398785102427676911360823387330617292042046112777895936"
    -- Yankel Scialom

  10. #10
    Membre à l'essai
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Points : 10
    Points
    10
    Par défaut
    Ah une réponse !

    Citation Envoyé par prgasp77 Voir le message
    Bonjour, <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Num.html#VALapprox_num_exp" target="_blank">Num.approx_num_exp</a> n'est-il pas ce qu'il te faut ?
    Oui, c'est une réponse alternative à ma première question, mais le vrai problème vient de la fonction "power_num" que je dois utiliser sur des nombres non entiers (et accessoirement positifs) mais qui n'est pas prévue pour ça.
    y'a t-il une solution pour pallier à ce problème ?

  11. #11
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Citation Envoyé par AlexiZ Voir le message
    mais le vrai problème vient de la fonction "power_num" que je dois utiliser sur des nombres non entiers (et accessoirement positifs) mais qui n'est pas prévue pour ça.
    y'a t-il une solution pour pallier à ce problème ?
    « Ha ! Une question ! » ais-je envie de dire. IL n'a jamais été question d'utiliser Num.power_num sur des rationnels avant ce message.

    Est-il possible de ruser ? Num.power_num accepte comme premier argument un ratio, mais requiert un entier en second argument. Sachant que :

    il est possible de contourner la limitation ... mais ... mais ... Num ne propose pas d'outil de calcul de racines. Il n'est donc pas adapté à tes besoins.

    Il va donc te falloir créer tes propres outils, mais ceux-ci dépendent de tes besoins. Peut être est-il temps pour toi de nous en dire un peu plus .
    -- Yankel Scialom

  12. #12
    Membre à l'essai
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par prgasp77 Voir le message
    « Ha ! Une question ! »
    Oui j'avais quelque peu abandonné le sujet sans réponse

    Comme dit dans un précédent message, l'idée est de calculer pi en utilisant la librairie Num. Or, dans mes différents algorithmes de calcul de pi (imposés malheureusement) j'utilise 6 fois sur 8 la fonction puissance ou la fonction racine.
    Et ces puissances / racines utilisent des décimaux...

    Comme "power_num" est ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    let power_num a b = match (a,b) with
      (n, (Int i)) -> power_num_int n i
    | (n, (Big_int bi)) -> power_num_big_int n bi
    | _ -> invalid_arg "power_num"
    c'est-à-dire sans décimaux, donc j'essaye de trouver une alternative. J'ai bien essayé la formule de Newton mais sans succès.

    Voilà je crois que j'ai exposé le problème un peu plus clairement.

    Donc l'objectif : transformer ma puissance décimale en autre chose de faisable pour un Num.

  13. #13
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Voici une implémentation de la méthode de Newton qui utilise Num. Mais c'est pas utilisable, je te dit pas le temps qu'il faut pour calculer la racine 4ième de 25 .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    (* Compilation
    	ocamlopt -o root nums.cmxa root_num.ml
    *)
     
    let root_num index radicand =
    	(* parameters *)
    	let max_iter = 1000000
    	and epsilon = Num.div_num (Num.Int 1) (Num.Int 1000000) in
    	(* constants *)
    	let one = Num.Int 1 in
    	let one_on_index = Num.div_num one index
    	and pred_index = Num.sub_num index one
    	in
    	(* Newton's methode *)
    	let rec aux iter acc index radicand =
    		if iter <= 0
    		then acc
    		else begin
    			(* New estimation *)
    			let new_acc =
    				Num.mult_num
    					one_on_index
    					(Num.add_num
    						(Num.mult_num pred_index acc)
    						(Num.div_num radicand
    							(Num.power_num acc pred_index)
    						)
    					)
    			in
    			(* check step *)
    			let step = Num.abs_num (Num.sub_num acc new_acc) in
    			if Num.le_num step epsilon
    			then new_acc
    			else aux (pred iter) new_acc index radicand
    		end
    	in
    	aux max_iter one index radicand
     
     
    (* help message *)
    let usage () =
    	Printf.printf "%s index radicand\n Compute the index-th root of radicand and print the result in standart output.\n" Sys.executable_name
     
     
    (* main *)
    let main () =
    	if Array.length Sys.argv != 3
    	then usage ()
    	else
    		let index = int_of_string Sys.argv.(1)
    		and radicand = int_of_string Sys.argv.(2)
    		in
    		let result =
    			Num.approx_num_exp 10
    				(root_num (Num.Int index) (Num.Int radicand))
    		in
    		Printf.printf "%s\n" result
     
     
    let _ = main ()
    -- Yankel Scialom

  14. #14
    Membre à l'essai
    Inscrit en
    Décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 15
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par prgasp77 Voir le message
    Voici une implémentation de la méthode de Newton qui utilise Num. Mais c'est pas utilisable, je te dit pas le temps qu'il faut pour calculer la racine 4ième de 25 .
    Effectivement, une simple racine cubique de 125 met plusieurs minutes
    Mais ça fonctionne ! Tu viens de résoudre mon problème en un seul post, bravo !

    Merci beaucoup !

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 06/12/2005, 16h54
  2. [D2005] Utilisation des types énumérés
    Par bouha dans le forum Delphi .NET
    Réponses: 2
    Dernier message: 21/07/2005, 22h21
  3. Erreur utilisation de type indéfini
    Par hanane_iaai dans le forum C++
    Réponses: 3
    Dernier message: 04/07/2005, 17h34
  4. [HTML]Utilisation du type file
    Par Kuroro dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 23/12/2004, 16h12
  5. utilisation du type DATE d'interbase
    Par dibak dans le forum InterBase
    Réponses: 4
    Dernier message: 05/01/2004, 15h03

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