hp41 et incrément registre

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
Avatar du membre
tyann
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 845
Enregistré le : 06 oct. 2012 14:37

hp41 et incrément registre

Message par tyann »

Bonjour

En programmant sur ma 41 deux petites fonctions destinées à compléter
le INT qui est en fait un Ipart car il renvoie la partie entière je me suis aperçu
d'un inconvénient.
Ceil et Floor les 2 fonctions que j'ai écrites renvoient l' entier immédiatement > et < à X.
J'ai essayé de rester dans l'esprit des fonctions intégrées et la pile n'est pas modifiée.

Petit bémol LastX restait à X+1 et X-1, seul reméde pour le modifier sans toucher la pile
l'incrémenter ou le décrémenter, mais la 41 ne dispose pas de ces fonctions (dommage).
Puis idée "géniale" utiliser DSE et ISG, comme l'opération peut se faire à la fin et que je crois avoir
lu quelque part que si ces 2 fonctions sont effectuées avant le END final quelque soit le résultat du test
c'est le END qui est bien exécuté.

Avec Ceil et DSE ça fonctionne nickel, mais avec Floor et ISG ça fonctionne presque ?
Lorsque X au départ vaut -0.xxxx Floor renvoie -1 et LastX vaut -1.xxx et aprés le ISG L
LastX vaut 0.xxx et non -0.xxx.

En fait ces deux fonctions n'agissent que sur la partie entière du registre et -0 n'existe pas je pense.
Car si ISG ajoutait 1 au registre par exemple sur -0.25 au lieu de passer à 1.25 on passerait à 0.75
et comme la partie fractionnaire sert de limite au compteur ça fouterait le bazar.
Cependant dans le cas précis où le registre contient -1.xxx, le signe de la valeur pourrait peut-être être conservé, alors bug ou pas ?
Ti(s) 60, 62 Galaxy, 66, 67 Galaxy, 68, 74 Basical 80, 81, 82, 83+, 83 CE, 84+SE, 85, 86, 89, 89 titanium, 92, 95 Procalc, v200, nSpire cx
Hp(s) 35s, 41CX, 28S, 48g, 50g, 39gII, Prime G1 et G2,
Casio(s) fx 602P, 702P, 4000P, 4500P, 6000G, 6900G, 7700G, 8500g, PB-700, CG-20, Graph 95 sd
Psion(s)II LZ64, siena, s3a, s3mx, s5mx.
Sharp(s) pc-1350, 1403, 1500A, E500, El 5120, 9200, 9600
Canon X-07
cgh
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 2142
Enregistré le : 30 août 2011 12:23
Localisation : Vous êtes ici -> .

Re: hp41 et incrément registre

Message par cgh »

Il n'y a pas de bug avec ISG et DSE.

Avec nnn.jjjii dans un registre R, ISG R incremente le registre R de ii et saute l'instruction suivante si nnn+ii > jjj.
Mais les cas dont tu parles ne sont pas geres. A l'epoquie INT correspondait a la truncation du nombre X (nnn.pppp devant nnn.0000) et non a la "partie entiere" comme on parle aujourd'hui.

Il faudrait que tu publies ton code si tu veux être aide...

Il y a pas mal d'astuces sur HP41 et cela poirrait etre l'objet d'un Misez p'tit, Optimisez ;)
Il y a ceux qui voient les choses telles qu'elles sont et se demandent pourquoi, et il y a ceux qui imaginent les choses telles qu'elles pourraient être et se disent... pourquoi pas? - George Bernard Shaw
J'adore parler de rien, c'est le seul domaine où j'ai de vagues connaissances ! - Oscar Wilde
Ce n'est pas parce que les choses sont difficiles que nous n'osons pas. C'est parce que nous n'osons pas que les choses sont difficiles. - Sénèque
Avatar du membre
tyann
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 845
Enregistré le : 06 oct. 2012 14:37

Re: hp41 et incrément registre

Message par tyann »

Salut Cgh

Voici le code pour Floor:

Code : Tout sélectionner

01 LBL "FLOOR"
02 X<0?
03 FS?30
04 GTO 00
05 SIGN
06 ST+L
07 X<>L
08 LBL 00
09 INT
10 X<0?
11 ISG L
12 END
 
et pour ceil

Code : Tout sélectionner

01 LBL "CEIL"
02 X<=0?
03 GTO 00
04 SIGN
05 ST+L
06 X<>L
07 LBL 00
08 INT
09 X>0?
10 DSE L
11 END
Ti(s) 60, 62 Galaxy, 66, 67 Galaxy, 68, 74 Basical 80, 81, 82, 83+, 83 CE, 84+SE, 85, 86, 89, 89 titanium, 92, 95 Procalc, v200, nSpire cx
Hp(s) 35s, 41CX, 28S, 48g, 50g, 39gII, Prime G1 et G2,
Casio(s) fx 602P, 702P, 4000P, 4500P, 6000G, 6900G, 7700G, 8500g, PB-700, CG-20, Graph 95 sd
Psion(s)II LZ64, siena, s3a, s3mx, s5mx.
Sharp(s) pc-1350, 1403, 1500A, E500, El 5120, 9200, 9600
Canon X-07
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3404
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: hp41 et incrément registre

Message par C.Ret »

Bonsoir,

J'essaie de comprendre ce que tu veux faire. Je n'ai pas compris pourquoi tu veux modifier la valeur du registre L:
Après l'utilisation de INT CEIL ou FLOOR, le registre L: ne doit pas simplement refléter la valeur initialement dans X: ?

Par contre, je vois bien le souci avec INT qui ne donne pas le résultat CEIL ou FLOOR selon le signe de l'argument en X:

Code : Tout sélectionner

X:      -145.2 -145.0 -144.9  -17.6  -17.4  -1.2  -1.0  -.9  -.4  0.0  0.4  0.9  1.0  1.2  17.4  17.6  144.9  145.0  145.2
INT     -145   -145   -144    -17    -17    -1    -1     0    0   0    0    0    1    1    17    17    144    145    145  
FLOOR   -146   -145   -145    -18    -18    -2    -1    -1   -1   0    0    0    1    1    17    17    144    145    145
CEIL    -145   -145   -144    -17    -17    -1    -1     0    0   0    1    1    1    2    18    18    145    145    146
RND	-145   -145   -145    -18    -17    -1    -1    -1    0   0    0    1    1    1    17    18    145    145    145
ON constate donc que INT est selon le signe de l'argument tantôt équivalent à la fonction CEIL (pour les X:<0) et la fonction FLOOR (pour les X:>0).

L'idée est donc de calculer INT(X) et de comparer avec X. Le signe de x fait que le sens de la comparaison s'inverse entre les positifs et les négatifs.
Donc, si l'on cherchait à calculer un FLOOR et que la comparaison montre que c'est loupé alors on corrige en décrémentant. Et réciproquement si l'on cherchait à calculer un CEIL et que l'on se rend compte que CEIL(X) est inférieur à X, alors on corrige en incrémentant.

D'où le code suivant, que j'ai trouvé dans la banque de données du MoHPC. Cela fait trois générations qui utilisent l'HP-41, il est bon de s'abreuver de l'expérience incommensurable collectée depuis plus de 41 ans !

Code : Tout sélectionner

01*LBL"CEIL"             
02 INT                // INT correspond à CEIL pour les x<0 sinon il faut incrémenter INT(X)+1 sauf si X étati initialement unentier
03 X<>Y
04 X<> L              // Sauvegarde registre Y: dans L:
05 X>Y?               // Si X>CEIL(X) alors on incrémente CEIL(X) (cas x>0 où CEIL(X)=INT(X)+1 ) ) 
06 ISG Y              // ATTENTION: le test en 07 est skippé, on va direct au GTO 00
07 X<=Y?              // ce test est toujours bon car c'est exactement l'opposé du celui en 05 (une sorte de NOP)
08 GTO 00             // on va rétablir le contenu intial de Y: et L:

09*LBL"FLOOR"
10 INT                // INT correspond à FLOOR pour les x>0 
11 X<>Y
12 X<> L              // sauvegarde registre Y: dans L:
13 X<Y?               // Si X>FLOOR(X) alors on décremente INT(X)  (cas x<0 où FLOOR(X)=INT(X)-1 ) 
14 DSE Y              // ATTENTION l'execution de DSE ne skippe pas nécessairement la ligne 15 (sauf si Y valait 1) 

15*LBL 00             // Sert aussi de NOP 
16 X<> L
17 X<>Y		      // rétablit la valeur intiale du registre Y: et replace le X: inital dans le registre L: 
18 END
Le fait qu'ici ISG Y (Incremente & Skip if Greater) saute systématiquement l'instruction suivante provient du fait qu'en Y: se trouve un entier. Et donc sauf s'il s'agissait de -1), le résultat de l'incrémentation sera toujours plus grande que la partie fractionnaire (les trois premières décimales) qui est nulle.

Inversement ,DSE Y (Decremente & Skip if Less or Egal) ne sautera pas l'instruction suivante sauf si Y était +1 ; le fraction décimale étant nulle il faut obtenir zéro.

Les instruction ISG/DSE des HP-41C, HP-15C, ... sont très différentes dans leur comportement et utilisation des instructions homologues des HP Classiques où ISZ et DSZ ne tiennent pas compte de la partie fractionnaire, mais uniquement du fait que le résultat de l'incrémentation ou de la décrémentation soit nul.

Ce code un un peu complexe car il préserve le contenu des registres T: Z: Y: , il remplace le contenu de X: par CEIL ou FLOOR et termine avec la valeur initiale de X: dans le registre L:

Ce qui est malin est d'échanger L: et Y: afin d'effectuer la comparaison entre le X initial et le résultat CEIL(X) et FLOOR(X) de façon vérifier en un seul test que c'est bon. Ce qui revient en quelque sorte à tester simultanément le signe de X et le fait qu'il soit ou non déjà un entier. Car, quelque soit le signe de X, si X=INT(X) il n'y a pas de correction (incrémentation ou décrémentation) à faire.
C'est malin.

(*) cf. P.S. de mon prochain post.
Modifié en dernier par C.Ret le 13 juin 2020 14:14, modifié 1 fois.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
tyann
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 845
Enregistré le : 06 oct. 2012 14:37

Re: hp41 et incrément registre

Message par tyann »

Bonjour

Merci Cret, effectivement j'ai compris le raisonnement et je suis
loin d'être au niveau :oops:
Ceci dit mes codes conservaient aussi la pile.
Oui comparer le résultat à la valeur de départ et incréménter ou
décrémenter l'entier est la bonne solution.
C'est toujours intéressant d'essayer de faire soi même ce qui existe déjà.
Et là j'ai bien compris la méthode, alors que si j'avais recopié le code ?
Cool.
Ti(s) 60, 62 Galaxy, 66, 67 Galaxy, 68, 74 Basical 80, 81, 82, 83+, 83 CE, 84+SE, 85, 86, 89, 89 titanium, 92, 95 Procalc, v200, nSpire cx
Hp(s) 35s, 41CX, 28S, 48g, 50g, 39gII, Prime G1 et G2,
Casio(s) fx 602P, 702P, 4000P, 4500P, 6000G, 6900G, 7700G, 8500g, PB-700, CG-20, Graph 95 sd
Psion(s)II LZ64, siena, s3a, s3mx, s5mx.
Sharp(s) pc-1350, 1403, 1500A, E500, El 5120, 9200, 9600
Canon X-07
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3404
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: hp41 et incrément registre

Message par C.Ret »

tyann a écrit : 13 juin 2020 09:05 [...]C'est toujours intéressant d'essayer de faire soi même ce qui existe déjà.
Et là j'ai bien compris la méthode, alors que si j'avais recopié le code ?[...]
Là je suis 10000% d'accord avec toi, je commence toujours par essayer avec mes propres moyens et mode de raisonnement. Le cas des FLOOR et CEIL est un cas qui m'a posé souci dès 1983 avec mon SHARP PC-1211 dont la fonction INT pose le même problème que l'INT des HP-41.

Et naturellement, j'ai eu la même approche que toi, mes codes testaient le signe de l'argument (on va dire de X) pour déterminer l'opportunité et le sens de la modification à faire pour obtenir un FLOOR ou un CEIL.
J'avoue que pour simplifier, je ne me mettais pas la pression en ne m'imposant pas de conserver la pile (d'ailleurs cela n'avait pas de sans en BASIC) ou le registre de sauvegarde LASTx. Mais rien que l'idée d'avoir un code aussi court que possible ou n'utilisant pas de test était parfois pour moi un vrai challenge.

Ce n'est effectivement qu'après avoir un peu souffert sur le problème, que jeter un œil sur ce qu'ont fait nos pères donne tout le bénéfice. D'abord parce que l'on comprend mieux les enjeux et ensuite très vite, si la méthode diffère complétement de sa propre approche, alors, il y a matière à remise en question et un potentiel progrès. Seul, je n'aurais jamais pensé à comparer le résultat de INT X avec X pour vérifier que j'ai bien effectué un CEIL ou un FLOOR. Sans me documenter, je serai resté à mon approche par étude de signes (héritage des méthodes d'analyses acquise au collège). Alors que l'approche ingénieuse est basée sur l'encadrement INT(X)-1 ≤ FLOOR(X) ≤ X ≤ CEIL(X) ≤ INT(X)+1

Ensuite, il y a les astuces pour sauvegarder et organiser la pile; c'est un exercice auquel je ne suis pas habitué.
J'ai une approche différente, j'utilise beaucoup la pile afin d'optimiser les opérations à effectuer (habitude prise en RPL). J'optimise les mouvements dans la pile en fonction des problèmes à résoudre, mais jamais je ne cherche à composer une bibliothèque de fonctions transparentes qui "ne modifient pas la pile". Je fais un peu l'inverse, pour moi la pile et la partie vivante du système et les codes que je composent agitent et font vibrer au maximum le cœur de nos machines.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
tyann
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 845
Enregistré le : 06 oct. 2012 14:37

Re: hp41 et incrément registre

Message par tyann »

Ce n'est effectivement qu'après avoir un peu souffert sur le problème, que jeter un œil sur ce qu'ont fait nos pères donne tout le bénéfice. D'abord parce que l'on comprend mieux les enjeux et ensuite très vite, si la méthode diffère complétement de sa propre approche, alors, il y a matière à remise en question et un potentiel progrès. Seul, je n'aurais jamais pensé à comparer le résultat de INT X avec X pour vérifier que j'ai bien effectué un CEIL ou un FLOOR. Sans me documenter, je serai resté à mon approche par étude de signes (héritage des méthodes d'analyses acquise au collège). Alors que l'approche ingénieuse est basée sur l'encadrement INT(X)-1 ≤ FLOOR(X) ≤ X ≤ CEIL(X) ≤ INT(X)+1
Oui c'est une bonne façon de progresser et je penserai à cela lorsque l'envie me prendra de réinventer à nouveau la roue sur ma 41.
Merci ce fut très enrichissant.
Néanmoins je me pose quand même la question : Est-il normal qu'un ISG -1.xxxx donne 0.xxx et non -0.xxxx ?
D'ailleurs je viens de faire l'essai sur une Ti 86 avec l'instruction IS>(var,valeur) qui est un équivalent à ISG
et on passe de -1.xxxx à -0.xxxx, donc le ISG de la 41 a tout de même un petit problème.
Ti(s) 60, 62 Galaxy, 66, 67 Galaxy, 68, 74 Basical 80, 81, 82, 83+, 83 CE, 84+SE, 85, 86, 89, 89 titanium, 92, 95 Procalc, v200, nSpire cx
Hp(s) 35s, 41CX, 28S, 48g, 50g, 39gII, Prime G1 et G2,
Casio(s) fx 602P, 702P, 4000P, 4500P, 6000G, 6900G, 7700G, 8500g, PB-700, CG-20, Graph 95 sd
Psion(s)II LZ64, siena, s3a, s3mx, s5mx.
Sharp(s) pc-1350, 1403, 1500A, E500, El 5120, 9200, 9600
Canon X-07
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3404
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: hp41 et incrément registre

Message par C.Ret »

tyann a écrit : 13 juin 2020 13:10[...]Néanmoins je me pose quand même la question : Est-il normal qu'un ISG -1.xxxx donne 0.xxx et non -0.xxxx ?
D'ailleurs je viens de faire l'essai sur une Ti 86 avec l'instruction IS>(var,valeur) qui est un équivalent à ISG
et on passe de -1.xxxx à -0.xxxx, donc le ISG de la 41 a tout de même un petit problème.
Non, c'est lié au fait que dans l'esprit des développeurs de chez HP, les fonctions ISG et DSE sont là pour faciliter les boucles et on ne peut faire de fraction de boucles. Ce sont donc uniquement des instructions manipulant des entiers. Le fait que la limite de la boucle et le pas soient codé dans la partie décimale est une astuce pour économiser des registres.

Dans cet esprit, si l'on veut faire des boucles où le compteur n'est pas entier ou varie d'un pas fractionnaire, alors il est préférable d'utiliser plusieurs registres et les tests habituels. Les instructions ISG et DSE sont comme leurs ancêtres ISZ et DSZ des outils pour des compteurs de boucle donc des entiers.

D'ailleurs dans les manuels des machines utilisant ces instructions, elles sont décrites dans un chapitre spécifique nommé "Boucles Contrôlées" et le registre utilisé est dénommé "nombres de contrôle" et on y parle de trois valeurs entières :
  • la valeur initiale ±aaaaa
  • la valeur finale bbb
  • et le pas de variation cc
Ces trois valeurs de contrôle sont regroupées au sein d'un même registre de dix chiffres sous la forme ±aaaaa.bbbcc et permettent de contrôler la répétition d'instructions en boucles.

Avec ISG, le ±aaaaa va être incrémenté par pas +cc. Le pas suivant est skippé uniquement si ±aaaaa > +bbb; la partie bbb est toujours positive ou nulle quelque soit le signe du registre de contrôle. Le signe du registre de contrôle reflète le signe de ±aaaa.

Avec DSE, le ±aaaaa va être décrémenté par ps de -cc. Le pas suivant est skippé uniquement si ±aaaaa ≤ +bbb; la partie bbb est toujours positive ou nulle quelque soit le signe du registre qui ne reflète que le signe de ±aaaaa.

Quelque soit les valeurs relatives de ±aaaaa et bbb, à chaque appel de ISG ou DSE, la valeur ±aaaaa est modifiée de +cc avec ISG et de -cc avec DSE. Par contre, le pas suivant est skippé ou non dépend de la comparaison stricte ( > ISG) ou non ( ≤ DSE) avec +bbb.

Notons que cette notion d'incrémentation (ou décrémentation) impérative chez HP fait qu'un pas de 00 est interprété comme un pas de 01. Je trouve cela un peu dommage mais c'est ainsi et cela est censé faire faire des économies de nibbles lors de la saisie ou programmation du registre de contrôle. Cela permet aussi de faire plein de choses facilement en MPO en utilisant directement des valeurs entières et adapter beaucoup plus facilement des codes anciens contenant les instructions ISZ et DSZ. En fait, je dis préférer avoir un pas nul, mais je suis un gros hypocrite, car c'est certainement là l'astuce que j'use et dont j'abuse le plus dans tous mes codes :twisted: :pirat:

Donc, oui, il est normal qu'un -1.xxx01 (ou -1.xxx00) incrémente le registre de contrôle en 0.xxx01 (respectivement 0.xxx00 ).
Par contre, le nombre de contrôle -1.xxxx sera incrémenté en yy.xxxx où yy=(x0)-1. En effet, -1.xxxx signifie ±aaaaa= -1 , bbb = xxx et cc= x0 après ISG, le nouveau compteur sera ±aaaaa= x0-1
De même -1.xxxxx deviendra yy.xxxxx avec yy = xx-1.

Les instructions ISG et DSE incrémentent et décrémentent le compteur de boucle ±aaaaa et non le registre de contrôle. L'incrémentation (ou décrémentation) d'un registre rr par une grandeur quelconque se fait plus facilement par RCL ii ST+ rr ou RCL ii ST- rr ou toute variation équivalente. ISG et DSE sont des instruction spécialisées dans le contrôle de boucles.


P.S.: Je me rends compte que j'ai mal nommé la fonction DSE dans mon poste précèdent, je corrige immédiatement.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
tyann
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 845
Enregistré le : 06 oct. 2012 14:37

Re: hp41 et incrément registre

Message par tyann »

Merci Cret pour toutes ces explications, je viens de refaire un teste sur Ti 86
où dans l'instruction IS>(var,valeur) var ne contient que la valeur à incrémenter
et valeur correspond à la valeur de test et effectivement avec -0.28 par exemple
on passe 0.72 et non à 1.28.
Ti(s) 60, 62 Galaxy, 66, 67 Galaxy, 68, 74 Basical 80, 81, 82, 83+, 83 CE, 84+SE, 85, 86, 89, 89 titanium, 92, 95 Procalc, v200, nSpire cx
Hp(s) 35s, 41CX, 28S, 48g, 50g, 39gII, Prime G1 et G2,
Casio(s) fx 602P, 702P, 4000P, 4500P, 6000G, 6900G, 7700G, 8500g, PB-700, CG-20, Graph 95 sd
Psion(s)II LZ64, siena, s3a, s3mx, s5mx.
Sharp(s) pc-1350, 1403, 1500A, E500, El 5120, 9200, 9600
Canon X-07
Répondre

Retourner vers « Tous les Pockets »