Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 14 sur 14
  1. #1
    Invité régulier
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 5
    Points
    5

    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 :
    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
    Rédacteur
    Avatar de SpiceGuid
    Homme Profil pro Damien Guichard
    Inscrit en
    juin 2007
    Messages
    1 569
    Détails du profil
    Informations personnelles :
    Nom : Homme Damien Guichard
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : juin 2007
    Messages : 1 569
    Points : 2 571
    Points
    2 571

    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 :
    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: 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.

  3. #3
    Invité régulier
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 5
    Points
    5

    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
    Rédacteur
    Avatar de SpiceGuid
    Homme Profil pro Damien Guichard
    Inscrit en
    juin 2007
    Messages
    1 569
    Détails du profil
    Informations personnelles :
    Nom : Homme Damien Guichard
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : juin 2007
    Messages : 1 569
    Points : 2 571
    Points
    2 571

    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: 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.

  5. #5
    Invité régulier
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 5
    Points
    5

    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
    Rédacteur
    Avatar de SpiceGuid
    Homme Profil pro Damien Guichard
    Inscrit en
    juin 2007
    Messages
    1 569
    Détails du profil
    Informations personnelles :
    Nom : Homme Damien Guichard
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : juin 2007
    Messages : 1 569
    Points : 2 571
    Points
    2 571

    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: 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.

  7. #7
    Invité régulier
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 5
    Points
    5

    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 Expert Avatar de prgasp77
    Homme Profil pro Yankel Scialom
    Ingénieur en systèmes embarqués
    Inscrit en
    juin 2004
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Nom : Homme Yankel Scialom
    Âge : 26
    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 084
    Points : 1 578
    Points
    1 578

    Par défaut

    Bonjour, Num.approx_num_exp n'est-il pas ce qu'il te faut ?

    Et je pense qu'il veut calculer dans .

  9. #9
    Membre Expert Avatar de prgasp77
    Homme Profil pro Yankel Scialom
    Ingénieur en systèmes embarqués
    Inscrit en
    juin 2004
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Nom : Homme Yankel Scialom
    Âge : 26
    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 084
    Points : 1 578
    Points
    1 578

    Par défaut

    Ha ! Et pour power :
    Code :
    1
    2
    3
    # Num.string_of_num (Num.power_num (Num.Int 504) (Num.Int 378)) ;;
    - : string =
    "33017392796145806168337542681632713604222995935988104123216879182928287894637048840597359552449336745902720910544576973376130276949945491709905194218388383927856494067568803810302723077080946938739059037654665557394630501724251429824678985000638923778108694450062077564482084416549777079249340604967521869646485255276241847131673592534722055015732764520610641645335086861421489622712513199518845994268387656780995195534217937542957200585918221068910253052292848581363845925365716402627687039286067310038747591656793390292631073518412591070311243669118312872835834456483469330329157209133904610082236915275558489487488920630490252596041569445152487024145367571764359878632171319807038019819019452538149624144276074228441991563894798422713706949206950320068915073838271807637016504830677150339287105118769260883601878681028320754504596371742050877247059336773795088839280844064430752831753633722391538027607060217484414866980566718815985992891941408840128305692064276730398785102427676911360823387330617292042046112777895936"

  10. #10
    Invité régulier
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 5
    Points
    5

    Par défaut

    Ah une réponse !

    Citation Envoyé par prgasp77 Voir le message
    Bonjour, Num.approx_num_exp 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 Expert Avatar de prgasp77
    Homme Profil pro Yankel Scialom
    Ingénieur en systèmes embarqués
    Inscrit en
    juin 2004
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Nom : Homme Yankel Scialom
    Âge : 26
    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 084
    Points : 1 578
    Points
    1 578

    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 .

  12. #12
    Invité régulier
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 5
    Points
    5

    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 :
    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 Expert Avatar de prgasp77
    Homme Profil pro Yankel Scialom
    Ingénieur en systèmes embarqués
    Inscrit en
    juin 2004
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Nom : Homme Yankel Scialom
    Âge : 26
    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 084
    Points : 1 578
    Points
    1 578

    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 :
    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 ()

  14. #14
    Invité régulier
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 5
    Points
    5

    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.

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
  •