[HP28S] Trouver la fraction de n'importe quel nombre...

Ici, on fait dans le petit, le LCD qui déchire sa race, on y cause même calculatrices quand on est en manque !

Modérateur : Politburo

Répondre
currybleu
Fonctionne à 75 bauds
Fonctionne à 75 bauds
Messages : 22
Enregistré le : 13 févr. 2013 15:43

[HP28S] Trouver la fraction de n'importe quel nombre...

Message par currybleu »

... y compris des nombres complexes, des racines carrées, etc...J'ai du écrire ce programme il y a une bonne vingtaine d'année mais je n'ai pas trouvé mieux, sur aucune calculatrice.
Ce programme n'a jamais été partagé car internet n'existait pas et puis je l'ai oublié. Pour ceux que ca intéresse, je le mets donc à dispo dans le but de l'optimiser et éventuellement qu'il puisse être porté sur d'autres calculatrices..
Pour le moment il fonctionne parfaitement sur HP28S mais pas sur sur HP50G (problème avec les fonction EXGET, OBJ-> à redéfinir) . Peut-être le trouverez-vous suffisamment intéressant pour le porter sur d'autres calculatrices...
Ce forum m'a l'air parfait pour ça :-)

Tout d'abord ce programme est divisé en 3 parties.
1- REDUC: ce programme permet de trouver la fraction de nombres tels que:
- 6.5 (13/2)
- 6.3333333333333333 (19/3)
- 3.14285714286 (22/7)
- ou même 6.456456456456456456 (2150/333)
bien sur il réduit également toute fraction au maximum

2- RACINE/ Ce programme permet de trouver les fractions des nombres ci-dessus en tenant compte de la racine carrée:
par exemple:
- 1.77281052086 donnera racine(22/7)
- 6.34227616011 donnera 32/9*racine(35/11)


3- FRAC. il s'agit du programme principal qui utilise les 2 autres. Il permet de trouver la fraction d'un nombre complexe, de la racine carrée d'un nombre complexe, d'une matrice, etc..
par exemple
- (1.3333333333333333+4.5i)/(7+6.4i)=0.423892100192+0.255298651253i
le resultat de FRAC donnera 220/519 + 265/1038i

Bien sûr, ca ne marche pas à tous les coups, mais l'avantage de ce programme, c'est que s'i ne trouve pas, le programme le sait tout de suite et ne part pas dans des calculs interminables.

Allons-y..


REDUC

Code : Tout sélectionner

<< DUP ->NUM 1.E12 * 1.E12 -> o n m
  << n ABS m
    DO SWAP OVER MOD
    UNTIL DUP 10000000 / IP NOT
    END DROP n OVER / IP DUP ABS m 4 ROLL / IP DUP
    IF 1 <>
    THEN 10 SF R->I ->STR "'" ROT R->I ->STR + "/" + SWAP + STR-> SWAP SIGN * DUP
      IF ->NUM o ->NUM - ABS .000000001 >
      THEN DROP o
      END
    ELSE DROP2
    END
  >>
>>
RACINE

Code : Tout sélectionner

<< EVAL
  IF REDUC DUP DUP TYPE SWAP DUP IP SAME OR NOT
  THEN
    << DUP DUP
      IF 1 <>
      THEN \/ IP 1 + -> a g
        << g 2
          FOR X
            IF a X SQ / DUP DUP IP ==
            THEN DUP a SWAP / \/ SWAP 0 'X' STO
            ELSE DROP
              IF X 2 <=
              THEN 1 a
              END
            END -1
          STEP
        >>
      END
    >> -> raci
    << DUP SIGN SWAP DUP SQ REDUC DUP DUP ->STR
      IF "." POS SWAP EVAL NOT OR NOT
      THEN SWAP DROP DUP
        IF TYPE NOT OVER DUP IP SAME OR
        THEN 1
        ELSE DUP 1 EXGET SWAP 3 EXGET
        END -> s n d
        << n raci EVAL d raci EVAL 4 ROLL ROT / REDUC 3 ROLLD / REDUC DUP ->STR -> p q
          << "'\/"
            IF p TYPE
            THEN "(" q 2 q SIZE 1 - SUB + ")" +
            ELSE q
            END + STR-> * s
          >>
        >>
      ELSE DROP
      END *
    >>
  END
>>
FRAC

Code : Tout sélectionner

<<
  IF 1 FS?
  THEN DUP 35 CF EVAL 35 SF
    IF TYPE NOT
    THEN RACINE
    ELSE
      IF DUP TYPE 1 ==
      THEN 10 SF DUP RE RACINE SWAP IM RACINE 'i' * +
      ELSE
        IF DUP TYPE DUP 3 == SWAP 4 == OR
        THEN ->STR "" SWAP
          DO DUP " " POS DUP2 1 SWAP SUB 3 ROLLD 1 + 999 SUB SWAP
            IFERR STR->
            THEN
            ELSE 10 CF FRAC ->STR
              IF 1 FC?
              THEN DUP DUP
                IF TYPE
                THEN SIZE 1
                ELSE SIZE 1 - 2
                END SWAP SUB
              END " " +
            END ROT SWAP + SWAP
          UNTIL DUP SIZE 2 <=
          END +
        ELSE
          IF DUP TYPE 9 ==
          THEN -> a
            << a 1 1 a SIZE
              FOR X -> y
                << a X EXGET
                  IF DUP TYPE 2 <
                  THEN FRAC DUP
                    IF TYPE 2 <
                    THEN 1
                    ELSE DUP SIZE
                    END -> s
                    << y SWAP EXSUB y s +
                    >>
                  ELSE DROP y 1 +
                  END
                >>
              NEXT
            >> DROP
          END
        END
      END
    END
  END
>>
Caractères à remplacer:
<> à remplacer par SHIFT = (différent)
\/ à remplacer par le caractere racine carrée
<= à remplacer par le caractère inférieur ou égal


N'hesitez pas si vous avez des questions, ça me fera plaisir de replonger dans ce code pour le porter sur HP50G par exemple
Avatar du membre
gege
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 7147
Enregistré le : 31 janv. 2008 14:24
Localisation : Banlieue Paârisienne
Contact :

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par gege »

Bonjour,
Sujet intéressant et je vais relire ton code avec attention.
Il y a quelques années je me suis cassé le bec sur le problème "tout simple" :
On connaît x, qui vaut a+b*sqrt(c). Trouver a, b et c...
Alors... je n'ai pas trouvé, si on exclut la recherche en force brute genre for a=-infini to +infini...
Idées bienvenue !
Mais ton programme fait peut-être cela, si oui chapeau !
G.E.
currybleu
Fonctionne à 75 bauds
Fonctionne à 75 bauds
Messages : 22
Enregistré le : 13 févr. 2013 15:43

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par currybleu »

Je suis en train de tester les programmes sur HP50G.
Pour l'instant je suis sur REDUC. qui est compatible.

ci-dessous le code pour la HP50G (j'imagine qu'il est également compatible avec les modèles 48 et 49? à confirmer:

Code : Tout sélectionner

%%HP: T(3)A(R)F(.);
\<< DUP \->NUM 1.E12 * 1.E12 \-> o n m
  \<< n ABS m
    DO SWAP OVER MOD
    UNTIL DUP 10000000. / IP NOT
    END DROP n OVER / IP DUP ABS m 4. ROLL / IP DUP
    IF 1. \=/
    THEN 10. SF R\->I \->STR "'" ROT R\->I \->STR + "/" + SWAP + STR\-> SWAP SIGN * DUP
      IF \->NUM o \->NUM - ABS .000000001 >
      THEN DROP o
      END
    ELSE DROP2
    END
  \>>
\>>

Le programme RACINE est également compatible HP50G
ci dessous le code correspondant pour la HP50G

Code : Tout sélectionner

%%HP: T(3)A(R)F(.);
\<< EVAL
  IF REDUC DUP DUP TYPE SWAP DUP IP SAME OR NOT
  THEN
    \<< DUP DUP
      IF 1 \=/
      THEN \v/ IP 1 + \-> a g
        \<< g 2
          FOR X
            IF a X SQ / DUP DUP IP ==
            THEN DUP a SWAP / \v/ SWAP 0 'X' STO
            ELSE DROP
              IF X 2 \<=
              THEN 1 a
              END
            END -1
          STEP
        \>>
      END
    \>> \-> raci
    \<< DUP SIGN SWAP DUP SQ REDUC DUP DUP R\->I \->STR
      IF "." POS SWAP \->NUM NOT OR NOT
      THEN SWAP DROP DUP
        IF TYPE NOT OVER DUP IP SAME OR
        THEN 1
        ELSE OBJ\-> DROP2
        END \-> s n d
        \<< n raci EVAL d raci EVAL 4 ROLL ROT / REDUC 3 ROLLD / REDUC DUP \->STR \-> p q
          \<< "'\v/"
            IF p TYPE
            THEN "(" q 2 q SIZE 1 - SUB + ")" +
            ELSE q
            END + STR\-> * s
          \>>
        \>>
      ELSE DROP
      END *
    \>>
  END
\>>
Pour tester, il suffit de rentrer votre nombre et de lancer RACINE. (bon le nom RACINE est super mal choisi.. je vais trouver autre chose ;-)

Sinon, pour répondre à ta question, le prohramme RACINE ne trouve pas de solution sous forme a+b*racine(c), mais uniquement a/b*racine(c/d).
Torlus
Administrateur
Administrateur
Messages : 1266
Enregistré le : 15 oct. 2005 22:33
Contact :

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par Torlus »

Ca remonte à loin, mais dès que t'as un pattern qui se répète, tu le divises par le même "nombre de 9" que la longueur du pattern, non ?
Genre 0, 235678 235678 235678 = 235678 / 999999.
22/7 = 3, 142857 142857 etc, on s'occupe pas du 3, et ça donne 142857 / 999999.
Après, un coup de PGCD et hop.
Ou j'ai rien compris ;)
gege a écrit : On connaît x, qui vaut a+b*sqrt(c). Trouver a, b et c...
Il manque une ou plusieurs contraintes, non ? ;)
"Pour finir, faut commencer."
"Il faut être un peu félé pour laisser passer la lumière".
currybleu
Fonctionne à 75 bauds
Fonctionne à 75 bauds
Messages : 22
Enregistré le : 13 févr. 2013 15:43

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par currybleu »

Torlus a écrit :Ca remonte à loin, mais dès que t'as un pattern qui se répète, tu le divises par le même "nombre de 9" que la longueur du pattern, non ?
Genre 0, 235678 235678 235678 = 235678 / 999999.
22/7 = 3, 142857 142857 etc, on s'occupe pas du 3, et ça donne 142857 / 999999.
en fait mon algo ne fonctionne pas comme ca.
grosso modo, il fonctionne par approximation, c'est à dire qu'il considére qu'il y a une solution lorsque la valeur entiere d'une division, divisée par 10000000 est inférieure à zero. (je sais c'est un peu imbitable,mais en pratique ca fonctionne plutot bien)
Pour faire simple, mon programme fonctionne tres bien pour 1.123123123123123123123 (374/333)... mais pas pour 1.12341234123412341234 car le dénominateur est trop grand...
Pour ton exemple, ca fonctionne bien. il me donne effectivement 22/7 (petit dénominateur inférieur à 1000)
si tu as l'occasion de le tester sur une HP?
Torlus
Administrateur
Administrateur
Messages : 1266
Enregistré le : 15 oct. 2005 22:33
Contact :

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par Torlus »

Ah non, je suis pas "caltocheux" ou "pocketeux" du tout, je ne pourrai pas aider, désolé ;)
C'était juste ma remarque à 2 balles, vu que le problème me rappelle une des questions que j'ai eu à l'oral d'un concours passé en prépa :
- soit A = 9876543210 ^ 123456789 (ou un truc du genre)
- soit B la somme des chiffres de A
- soit C la somme des chiffres de B
Calculer C.
"Pour finir, faut commencer."
"Il faut être un peu félé pour laisser passer la lumière".
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par Gilles59 »

Hello Currybleu ! Bienvenue sur Silicium ;)

Sur la 50G tu as la commande →Q qui peut facilter les choses et qui fonctionne étonnamment bien (menu CONVERT REWRITE NXT)

ce qui est sympa c'est qu'elle fonctionne en fonction de FIX.

Par exemple :

2 FIX
3.1415926 →Q donne 22/7

en mode FIX 'normal'

PI →Q donne '1146408/364913' (c'est instantané !)

Dans le même genre,il y a la commande ->Qπ

2.35619449019 →Qπ donne '3/4 π'
.1234 →Qπ donne '617/5000'

Ca fonctionne aussi avec les nombres complexes.

0.423892100192+0.255298651253i
->Q donne :

'(377815125178001928503+227547745846008946169*i)/891300227123938488689'

en FIX5

'(440+265*i)/1038'

par contre, il n'y a pas de commande native pour les racines
Casio FX-502P /602P / 603P / FX180P+ / FX4000P / TI57 / TI66 / TI74 Basicalc / TI95 Procalc / HP12C / HP15C LE / DM41L / HP 30B / HP39GII / HP 48SX USA / 49G / 49g+ / 50G / 50G NewRPL / HP Prime / Oric 1 / Amstrad CPC 6128+ CM14 et MM12 / Alice 32
Avatar du membre
gege
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 7147
Enregistré le : 31 janv. 2008 14:24
Localisation : Banlieue Paârisienne
Contact :

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par gege »

Torlus a écrit :Ca remonte à loin, mais dès que t'as un pattern qui se répète, tu le divises par le même "nombre de 9" que la longueur du pattern, non ?
Effectivement, c'est une très bonne idée, sauf que la période peut être longue, et tu manques vite de chiffres pour la détecter. Exemple : 1/38 a une période de 18 chiffres...
Mais en théorie ta technique est parfaite.

Je recommande plutôt la méthode des fractions continues, exemple sur cette page :wink: .
Torlus a écrit :
gege a écrit : On connaît x, qui vaut a+b*sqrt(c). Trouver a, b et c...
Il manque une ou plusieurs contraintes, non ? ;)
Ben non, et c'est peut-être pour ça qu'on ne trouve pas.
Pas complètement évident, par exemple le problème assez proche :
"On connaît x, qui vaut a+b*sqrt(5). Trouver a et b..." est facile.

G.E.

P.S. : boutrecornegidouille, ça n'a pas l'air facile de trouver C !!!
currybleu
Fonctionne à 75 bauds
Fonctionne à 75 bauds
Messages : 22
Enregistré le : 13 févr. 2013 15:43

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par currybleu »

Gilles59 a écrit : 0.423892100192+0.255298651253i
->Q donne :'(377815125178001928503+227547745846008946169*i)/891300227123938488689'
en FIX5
'(440+265*i)/1038'
par contre, il n'y a pas de commande native pour les racines
la fonction ->Q m'a l'air intéressante à utiliser. il doit donc être possible d'optimiser mon programme avec.
en attendant, en lançant le programme RACINE pour les nombres suivants, on trouve;
0.423892100192+0.255298651253i -> 220/519 + 265/1038*i (faction réduite au maximum)
ainsi que
racine(0.423892100192) + racine(0.255298651253)*i soit 0.50527086919 + 0.651069965666*i -> racine(265/1038) + 2*racine(55/519)*i :D
Avatar du membre
gege
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 7147
Enregistré le : 31 janv. 2008 14:24
Localisation : Banlieue Paârisienne
Contact :

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par gege »

Bonjour,
En cherchant un truc je tombe sur une EL9200, qui contenait ce programme :

Code : Tout sélectionner

ClrT
Print "Nombre
Input x
x=abs fpart x
Print x
y=x
x=x^-1
n=12
dim F[1,n]
i=1
Label 1
F[1,i]=ipart x
x=1/fpart x
If 1e-3>abs(1-x*y)Goto 4
i=i+1
If i>nGoto 2
If x<1e3Goto 1
Print "Exact
Label 2
Print "Fraction
a=0
b=1
Label 3
i=i-1
c=F[1,i]*b+a
a=b
b=c
If i>1Goto 3
Print a
Print b
x=a/b
Print x
End
Label 4
Print "(a+Vb)/c
a=1
b=0
c=0
d=1
Label 5
e=C
f=d
c=a+c*F[1,i]
d=b+d*F[1,i]
a=e
b=f
i=i-1
If i>0Goto 5
b=(d-a)^2+4*c*b
a=a-d
c=2*c
Print a
Print b
Print c
On ne tient pas compte du signe ni de la partie entière, qui ne servent en fait à rien (n'est-ce pas ?).
Exemple d'utilisation : (lancer le programme)
Nombre
x=?
taper 0.215250437
(a+Vb)/c
a=
-12
b=
252
c=
18

Soit 0.215250437 = (V7-2)/3

Purée qu'elle est lente la EL9200 !! Sympa pourtant comme machine.

Ca résoud donc le problème que je qualifiais d' "insoluble" ci-dessus, mais souvent le programme interprète un nombre comme une fraction, ceci est dû au fait que la tolérance est positionnée assez bas.
Autre méthode, sachant que la fraction continue (le tableau F ci-dessus) d'une expression contenant une racine carrée est forcément périodique à partir d'un certain moment, il 'suffit' de détecter cette période... facile à dire !

Bon j'arrête les maths quelque temps.
G.E.
Avatar du membre
Paul Tergeist
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2417
Enregistré le : 15 oct. 2007 15:50
Localisation : 3ème planète après le soleil

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par Paul Tergeist »

Damned, je peste de ne pas avoir encore retrouvé ma HP-28S.
Et Gégé est encore dans le coup.
Le même Gégé qui a fait le site que j'ai visité il y a quelques années et
qui m'a donné envie de faire ma collection. Il n'arrêtera donc jamais ?
Par l'Oeuf !

Paul
Avatar du membre
gege
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 7147
Enregistré le : 31 janv. 2008 14:24
Localisation : Banlieue Paârisienne
Contact :

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par gege »

:D bon retour au fait Paul, ça fait plaisir de te relire.
Tu nous a manqué !
A+
G.E.
Avatar du membre
Paul Tergeist
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2417
Enregistré le : 15 oct. 2007 15:50
Localisation : 3ème planète après le soleil

Re: [HP28S] Trouver la fraction de n'importe quel nombre...

Message par Paul Tergeist »

Vous aussi mais je n'ai rien pu faire, une de mes autres personnalités avait pris
le contrôle et prenait des somnifères pour éviter que je ne redevienne la personnalité majeure.

Heureusement mon psychiatre est intervenu lorsqu'il s'est rendu compte que je ne venais
plus aux rendez-vous.

Mais bon, d'après mes amis l'autre était mieux. :(
Répondre

Retourner vers « Tous les Pockets »