Section courante

A propos

Section administrative du site

La bibliothèque SANE

Cette annexe décrit le SANE (Standard Apple Numeric Environment) et les routines contenues dans les bibliothèques SANE SANELib.o et SANELib881.o. Il contient deux parties :

SANE est la base des calculs mathématiques à virgule flottante effectués par MPW Pascal. Il répond à toutes les exigences en matière d'arithmétique à virgule flottante de précision étendue, telles que prescrites par les normes IEEE 754 et 854. Il garantit que toutes les opérations en virgule flottante sont effectuées de manière cohérente et qu'elles renvoient les résultats les plus précis possibles.

SANE fournit un environnement flexible et facile à utiliser pour les calculs en virgule flottante. Il vous donne des résultats extrêmement précis sans codage supplémentaire. Vous pouvez écrire des programmes ANS Pascal standard en utilisant uniquement le type réel et être sûr que vos résultats sont aussi précis que possible dans ce format.

Si vous êtes intéressé par une précision au-delà de celle possible en utilisant uniquement le type réel, vous pouvez utiliser les autres types à virgule flottante fournis comme extension de Pascal par SANE. De plus, la bibliothèque SANE contient des fonctions numériques introuvables dans le Pascal standard et des routines permettant de contrôler l'environnement dans lequel les calculs en virgule flottante sont effectués.

Cette annexe présente la version de SANE disponible sur tous les Macintosh. Sur les Macintosh équipés d'un 68020 et d'un 68881 (comme le Macintosh II), les paquets SANE peuvent appeler le 68881 pour les fonctions arithmétiques de base. Cette annexe fournit également des informations sur les 68881 fonctions transcendantales.

Les types de données SANE

La spécification originale de Pascal n'appelait qu'un seul type de données à utiliser avec les nombres à virgule flottante : le type réel. Le MPW Pascal étend le langage de programmation avec quatre types : single, double, extended et comp.

Remarque : La norme ANSI spécifie que toute implémentation de Pascal répondant à ses critères ; les exigences doivent inclure un type nommé real. Le type unique MPW Pascal et le type réel ANS Pascal sont synonymes. Le compilateur MPW Pascal acceptera l'un ou l'autre de ces termes et les traitera exactement de la même manière.

Descriptions des types

Le type unique est le plus petit format utilisé avec les nombres à virgule flottante. Il entrepose les nombres à virgule flottante en utilisant 32 bits d'entreposage.

Le type double est deux fois plus grand que le type single. Il utilise 64 bits pour l'entreposage.

Le type étendu est encore plus grand : il utilise un format 80 bits. Toutes les arithmétiques impliquant des valeurs de type real sont effectuées en utilisant le type étendu. Le type extended occupe 96 bits lorsque l'option -MC68881 est appelée.

Le type comp entrepose les valeurs intégrales au format 64 bits. Il est classé comme un type real car l'arithmétique à précision étendue est effectuée avec des opérandes de type comp et utilise le type extended. Les résultats affectés à une variable de type comp sont convertis depuis extended.

Les types single, double et extended sont définis par la norme IEEE.

Choisir un type de données

En règle générale, le choix d'un type de données nécessite que vous déterminiez les compromis entre :

La précision, l'intervalle et l'utilisation de la mémoire pour chaque type de données SANE sont indiquées dans le tableau suivant :

Identificateur de type Single Double Comp Extended *
 Taille (octets : bits) 4:32 8:64 8:64 10:80
Intervalle d'exposant binaire
 Minimum -126 -1022 - -16383
 Maximum 127 1023 - 16383
Précision significative
 Bits 24 53 63 64
 Chiffres décimaux 7 à 8 15 à 16 18 à 19 19 à 20
Intervalle décimale (approximative)
 Minimum négatif -3.4E+38 -1.7E+308 -9.2E18 -1.1E+4932
 Norme négative maximale -1.2E-38 -2.3E-308   -1.7E-4932
 Dénormation négative maximale   -1.5E-45 -5.0E-324 -1.9E-4951
 Dénorme positive minimale   1.5E-45 5.0E-324 1.9E-4951
 Norme minimale positive 1.2E-38 2.3E-308   1.7E-4932
 Positif maximum 3.4E+38 1.7E+308 ≈9.2E18 1.1E+4932
 Infinis Oui Oui Non Oui
 Pas un Nombre (NaN) Oui Oui Oui Oui

* Lorsque -MC68881 est appelé, le type étendu occupe 12 octets, soit 96 bits. Il n'y a aucun autre changement dans les types de données dans ce tableau.

De nombreux programmes nécessitent un type de comptage comptant exactement les choses (centimes, dollars, widgets). En utilisant SANE, vous pouvez écrire un programme traitant les valeurs monétaires en représentant ces valeurs sous forme de nombres entiers de cents ou de mils, pouvant être entreposés exactement dans le type comp. La somme, la différence ou le produit de deux valeurs de comparaison est exact si l'ampleur du résultat ne dépasse pas 263-1 (c'est-à-dire 9223372036854775807). De plus, les valeurs comp (par exemple, les résultats des calculs comptables) peuvent être mélangées avec des valeurs étendues dans les calculs à virgule flottante (comme les intérêts composés).

L'arithmétique avec des variables de type comp, comme toute l'arithmétique SANE, est effectuée en interne en utilisant le type étendu pour l'arithmétique. Il n'y a aucune perte de précision, car la conversion de comp en extend est toujours exacte. Vous pouvez économiser de l'espace en entreposant les nombres dans le type comp, étant plus court qu'extended.

Valeurs représentées

Les types à virgule flottante (single, double et extended) entreposent les représentations binaires d'un signe (+ ou -), d'un exposant et d'une mantisse. Un nombre représenté a la valeur :

± mantisse * 2 exposant

où pour les nombres normalisés, la mantisse a un seul bit à gauche du point binaire (c'est-à-dire 0 ≤ mantisse < 2).

Intervalle et précision des types SANE

L'intervalle et la précision des types réels pris en charge par SANE et MPW Pascal sont présentées dans le tableau précédent. Les intervalles décimales sont exprimées sous forme de représentations décimales hachées à deux chiffres des valeurs binaires exactes.

Exemples

En utilisant le type unique, le plus grand nombre représentable a :

significatif = 2 - 2-23
= 1.111111111111111111111112
exposant - 127
valeur = (2 - 2-23 ) * 2127
≈ 3.403 * 1038

le plus petit nombre normalisé positif représentable a :

significatif = 1
= 1.000000000000000000000002
exposant = -126
valeur = 1 * 2-126
≈ 1.175 * 10-38

et le plus petit nombre dénormalisé positif représentable a :

significatif = 2-23
= 0.000000000000000000000012
exposant = -126
valeur = 2-23 * 2-126
≈ 1.401 * 10-45

Le type Single

Le format single 32 bits est divisé en trois champs, comme illustré dans l'image suivante :

La valeur v du nombre est déterminée par ces champs :

Le type Double

Un nombre double de 64 bits est divisé en trois champs :

La valeur v du nombre est déterminée par ces champs :

Le type Comp

Un numéro de comp de 64 bits est divisé en deux champs :

La valeur v du nombre est déterminée par ces champs :

Le type Extended

Un nombre de format extended de 80 bits est divisé en quatre champs :

La valeur v du nombre est déterminée par ces champs :

Le format étendu 96 bits utilisé lorsque -MC68881 est appelé ne diffère du format 80 bits que par l'inclusion de 16 bits d'espace inutilisé :

Arithmétique étendue

Alors que les types MPW Pascal single, double et comp sont destinés à un entreposage de données économique, le type étendu constitue la base de tous les calculs arithmétiques. Comme spécifié par la norme IEEE, toutes les opérations arithmétiques de base, y compris l'addition, la soustraction, la multiplication, la division et l'extraction de racine carrée, donnent les meilleurs résultats possibles. Dans MPW Pascal, ces opérations produisent des résultats étendus, ils sont donc précis avec une précision de 19 chiffres décimaux sur 2 intervalles dépassant 10-4900 à 10+4900.

Le MPW Pascal tire parti de l'arithmétique étendue en entreposant toutes les constantes numériques non entières au format étendu et en évaluant toutes les expressions numériques non entières en étendues, quels que soient les types impliqués. Par exemple, tout le côté droit de l'affectation ci-dessous sera calculé en étendu avant d'être converti dans le type du côté gauche :

  1. Var
  2.  x,a,b,c:Real;
  3. BEGIN
  4.  x:=(b+Sqrt(b*b-a*c))/a;
  5. END.

Sans effort particulier de la part du programmeur, MPW Pascal effectue des calculs en utilisant la précision et la portée du type extended. Une précision supplémentaire signifie des erreurs d'arrondi plus petites afin que les résultats soient plus précis, plus souvent. Une portée supplémentaire signifie que les débordements et les sous-débordements sont moins fréquents, de sorte que les programmes fonctionnent plus souvent.

En suivant quelques pratiques de programmation simples, vous pouvez exploiter le type étendu au-delà de ce que MPW Pascal fait automatiquement pour vous.

Déclarez les variables utilisées pour les résultats intermédiaires comme étant de type étendu. Cette pratique est illustrée dans l'exemple suivant, calculant une somme de produits :

  1. Var
  2.  Sum:Real;
  3.  X,Y:Array[1..n] of Real;
  4.  I:Integer;
  5.  T:Extended; {détient des résultats intermédiaires}
  6. BEGIN
  7.  T:=0.0;
  8.  For I:=1 TO n DO T:=T+X[I]*Y[I];
  9.  Sum:=T;
  10. END.

Si T avait été déclaré réel, comme les tableaux d'entrée X et Y et la somme des résultats, à chaque fois dans la boucle, l'affectation à T aurait provoqué une erreur d'arrondi à la limite de la simple précision. Dans l'exemple, toutes les erreurs d'arrondi sont à la limite de la précision extended, à l'exception de celle provoquée par l'affectation de T à la somme. Cela signifie que les erreurs d'arrondi seront moins susceptibles de s'accumuler pour produire un résultat inexact.

Déclarez les paramètres de valeur formelle et les résultats de fonction comme étant de type étendu, plutôt que Real, Double ou Comp. Cela évite à MPW Pascal d'avoir à effectuer des conversions inutiles entre les types numériques, ce qui peut entraîner une perte de précision. L'exemple ci-dessous illustre cette pratique.

  1. Function Area(Radius:Extended):Extended;Begin
  2.  Area:=Pi*Radius*Radius
  3. End;

Cas spéciaux

Bien que l'utilisation du type étendu fasse fonctionner les programmes plus souvent, des cas exceptionnels surviennent. Vos programmes peuvent contenir des instructions comme celles-ci :

  1. Average:=Sum/Count;
  2. Area:=Side*Side;

où toutes les variables sont de type Real. Que se passe-t-il si le nombre est nul, si le nombre et la somme sont tous deux nuls ou si le produit Side*Side est trop grand pour être représenté dans le format réel ?

Le MPW Pascal attribue des valeurs spéciales à Average et Area, et votre programme continue. En fait, la norme IEEE fait référence aux "exceptions" plutôt qu'aux "erreurs" et spécifie "pas d'arrêt" comme mode de fonctionnement par défaut pour son arithmétique. Si vous devez réinstaller les valeurs par défaut de l'IEEE, vous utiliserez cette instruction :

  1. SetEnvironment(IEEEDefaultEnv);

Notez que le type Environment n'est pas le type integer lorsque l'option -MC68881 est appelée, donc l'ancienne utilisation, SetEnvironment(0), ne fonctionnera plus avec cette option. Pour des raisons de compatibilité, SetEnvironment(IEEEDefaultEnv) fonctionne correctement quel que soit le paramètre de l'option -MC68881.

La bibliothèque SANE contient également des fonctions et des procédures permettant de déterminer quand des cas exceptionnels se produisent.

Classes de nombres

Les représentations dans les formats de données SANE se répartissent en cinq classes :

Infinis

Les infinis sont des représentations SANE spéciales pouvant survenir de deux manières à partir d'opérations sur des valeurs finies :

MPW Pascal prédéfinit la constante inf pour avoir la valeur positive à l'infini. La constante de chaîne de caractères inf représente également l'infini pour l'entrée et la sortie de valeurs à virgule flottante. Les infinis se comportent comme des infinis mathématiques; par exemple, 1-inf =-inf. Les infinis peuvent être utiles même lorsque «l'arithmétique à l'infini» n'est pas l'objectif; par exemple, si x * x est trop grand pour le format étendu, l'expression 1+1/(X*X) calcule toujours la valeur correcte de un (en supposant que les arrêts de débordement sont désactivés).

Essaye ça :

  1. Program UseInf;
  2. Uses SANE;
  3. Var
  4.  X:Extended;
  5. BEGIN
  6.  X:=1e4000;
  7.  WriteLn('X*X=',X*X);
  8.  WriteLn('1/(X*X)=',1/(X*X));
  9.  WriteLn('1+1/(X*X)=',1+1/(X*X))
  10. END.

NaN

Une autre représentation SANE spéciale est un NaN (Not a Number). Un NaN est produit chaque fois qu'une opération ne peut pas produire un résultat numérique significatif. Par exemple, 0/0 et Sqrt(-1) produisent des NaN.

Lorsqu'un NaN est généré par le logiciel SANE ou par des routines dans une bibliothèque SANE, un code NaN associé est renvoyé dans le cadre de la représentation du NaN. Ce code vous indique quel type d'opération a provoqué la création du NaN. Les codes NaN, présentés dans le tableau suivant, peuvent aider au débogage :

Code Description
1 Racine carrée non valide, telle que Sqrt(-1)
2 Ajout non valide, tel que (+inf) - (+inf)
4 Division invalide, telle que 0/0
8 Multiplication non valide, telle que 0 * inf
9 Reste ou MOD non valide, tel que X MOD 0
17 Tentative de conversion d'une chaîne ASSII non valide
20 Résultat de la conversion du comp NaN en format à virgule flottante
21 Tentative de création d'un NaN avec un code zéro
33 Paramètre invalide pour la routine de déclenchement
34 Paramètre invalide pour la routine de déclenchement inverse
36 Paramètre non valide pour enregistrer la routine
37 Paramètre non valide pour la routine xi ou xy
38 Paramètre invalide à la fonction financière

Tous les NaN générés par le 68881 auront un code NaN de 255.

Important : Lorsque l'option -MC68881 est définie, de nombreux NaN du tableau précédent sont générés par le 68881; par conséquent, vous ne recevrez pas tous les paramètres répertoriés dans ce tableau.

L'instruction WriteLn(0/0) produira le résultat NAN(004) (à condition que l'arrêt de l'opération non valide soit désactivé). NAN(004), nan(4) et NaN sont des exemples d'entrées acceptables pour lire un NaN dans une variable SANE.

Nombres dénormalisés

Dans la mesure du possible, SANE entrepose les valeurs sous forme normalisée : le bit le plus significatif de la mantisse est un un plutôt qu'un zéro.

Cependant, lorsqu'un très petit nombre est entreposé et que l'exposant est la plus petite valeur négative possible, il est possible d'entreposer des valeurs encore plus petites en entreposant des zéros non significatifs. Par exemple :

En raison des nombres dénormalisés, l'arithmétique IEEE a la propriété souhaitable que a <> b si et seulement si a - b <> 0. Dans la plupart des arithmétiques non IEEE, a - b "rentrera à zéro" si a - b est trop petit, pour une représentation normalisée, même si a et b peuvent avoir des valeurs différentes.

Conditions exceptionnelles

Des conditions exceptionnelles peuvent résulter des calculs en virgule flottante dans un certain nombre de cas. Par exemple, la multiplication de deux valeurs très grandes peut entraîner une valeur trop grande pour être représentée dans l'un des formats de données MPW Pascal. Ou une opération telle que 0/0 peut être effectuée.

Le SANE permet à un programme de déterminer quand un calcul en virgule flottante a abouti à l'une de ces conditions exceptionnelles. Les conditions exceptionnelles se répartissent en cinq catégories :

Opération invalide

L'exception d'opération non valide survient lorsque les opérandes d'une opération ne sont pas valides, de sorte qu'un résultat numérique significatif est impossible. Par exemple, 0/0 et Sqrt(-1) sont des opérations non valides.

Sous-débordement

Un sous-débit se produit lorsqu'un résultat est à la fois dénormalisé et a perdu des chiffres significatifs en raison de l'arrondi. Par exemple, pour renvoyer le résultat de :

(1.000000000000000000000012 * 2-126) / 2

au format réel, un zéro non significatif serait introduit et le dernier bit significatif serait perdu lors de l'arrondi. Le résultat :

0.10000000000000000000000002 * 2126

serait restitué et le sous-débordement serait signalé

Débordement

Un débordement se produit lorsqu'une valeur calculée est trop grande pour tenir dans le format de son type désigné. Le format de destination doit être l'un des types à virgule flottante ; si le format de destination est un type entier, l'exception non valide se produit.

Division par zéro

L'exception de division par zéro se produit lorsqu'un nombre fini non nul est divisé par zéro. Cela se produit également lorsqu'une opération sur des opérandes finis produit un résultat infini exact. Par exemple, l'opération 1/0 (aboutissant à INF) et l'opération Ln(0) (qui aboutit à -INF) signalent toutes deux une division par zéro.

Inexact

L'exception inexacte se produit lorsque le résultat arrondi d'une opération n'est pas identique au résultat mathématique (exact). (Ainsi, chaque fois qu'un dépassement ou un dépassement inférieur se produit, l'exception inexacte est signalée.) Par exemple, l'opération 2/3 signale une erreur inexacte, quel que soit le format à virgule flottante utilisé.

L'environnement SANE

L'«environnement» SANE est constitué de :

La bibliothèque SANE comprend des procédures et des fonctions permettant de déterminer l'état actuel de l'environnement. Ces procédures et fonctions peuvent être utilisées pour signaler des conditions exceptionnelles et pour contrôler les paramètres d'environnement facultatifs. Par exemple, vous travaillez peut-être avec de très petites valeurs et avez besoin de savoir exactement quand un dépassement inférieur se produit. Ou vous souhaiterez peut-être que les conversions en virgule flottante soient arrondies à la baisse.

Les interfaces et bibliothèques SANE

Cette section explique chacune des constantes, types, fonctions et procédures contenus dans les interfaces et bibliothèques SANE. La bibliothèque SANELib881.o contient les mêmes procédures et fonctions disponibles dans SANELib.o mais doit être utilisée lorsque vous avez appelé l'option du compilateur -MC68881. La plupart du code SANE réel se trouve dans Pack4 et Pack5. SANELib.o et SANELib881.o contiennent des interfaces de code avec Pack4 et Pack5. Le fichier SANE.p contient le texte d'interface pour SANE.

Descriptions des constantes et des types

Chacune des constantes et des types définis par l'interface SANE est brièvement abordée dans la section suivante. Pour plus d'informations, consultez les descriptions des procédures et fonctions spécifiques mentionnées.

La constante DecStrLen

DecStrLen (longueur de chaîne de caractères décimale) est défini par :

  1. DecStrLen = 255;

DecStrLen est la constante définissant la longueur maximale d'une chaîne numérique décimale. C'est l'attribut size des variables de type DecStr.

Constantes de condition d'exception

Les déclarations définissant les cinq constantes de condition d'exception utilisées lorsque vous n'avez pas appelé l'option -MC68881 sont :

  1. Const
  2.  Invalid=1;
  3.  Underflow=2;
  4.  Overflow=4;
  5.  DivByZero=8;
  6.  Inexact=16;

Ces constantes permettent de définir la valeur d'une variable de type Exception.

Par exemple, si e est une variable de type Exception, alors :

  1. e:=Invalid+Overflow+DivByZero;

donne une valeur représentant ces trois exceptions collectivement.

Les routines SetException, TestException, SetHalt et TestHalt acceptent toutes des arguments de type Exception.

Les déclarations définissant les 13 constantes de condition d'exception utilisées lorsque vous avez appelé l'option -MC68881 sont :

  1. Const
  2.  Inexact=8;
  3.  DivByZero=16;
  4.  Underflow=32;
  5.  Overflow=64;
  6.  Invalid=128;
  7.  CurInex1=256;
  8.  CurInex2=512;
  9.  CurDivByZero=1024;
  10.  CurUnderflow=2048;
  11.  CurOverflow=4096;
  12.  CurOpError=8192;
  13.  CurSigNaN=16384;
  14.  CurBSonUnor=32768;

Reportez-vous au manuel d'utilisation du coprocesseur à virgule flottante MC68881 pour plus d'informations sur les exceptions 68881.

Le type DecStr

La déclaration définissant le type DecStr est :

  1. DecStr = STRING[DecStrLen];

Le type DecStr est une chaîne de caractères avec un attribut size de DecStrLen, soit 255 caractères. Il est utilisé pour contenir la représentation décimale, en caractères ASCII, d'un nombre.

Le type d'enregistrement DecForm

Un enregistrement de type DecForm (Decimal Format) est défini par cette déclaration :

  1. DecForm=RECORD
  2.  Style:(FloatDecimal,FixedDecimal);
  3.  Digits:Integer
  4. END;

Un enregistrement DecForm contient les spécifications du format d'un nombre décimal.

La procédure Num2Str prend un argument DecForm. Elle utilise les informations de DecForm pour déterminer le format de la chaîne de caractères à renvoyer.

Le type RelOp

Le type RelOp (Relational Operator) est défini par :

  1. RelOp = (GreaterThan, LessThan, EqualTo, Unordered);

Un résultat de ce type est renvoyé par la fonction Relation, décrite plus loin.

Le type NumClass

Le type NumClass est défini par :

  1. NumClass = (SNaN, QNaN, Infinite, ZeroNum, NormalNum, DenormalNum);

Descriptions des classes de nombres :

Classe de nombres Descriptions
SNaN Signalisation NaN
QNaN NaN silencieux
Infinite Infini ou -Infini
ZeroNum 0 ou -0
NormalNum Nombre normalisé
DenormalNum Numéro dénormalisé

Les NaN silencieux sont le type habituel produit par les opérations à virgule flottante. Les NaN de signalisation, potentiellement utiles pour signaler les variables non initialisées, sont abordés dans le manuel Apple Numerics.

Le type NumClass est utilisé pour renvoyer les résultats des fonctions d'interrogation, décrites ci-dessous.

Le type Exception

Une variable de type Exception contient une valeur entière correspondant à la valeur de l'une des constantes Exception ou à une somme de deux ou plusieurs constantes Exception. Sauf si l'option -MC68881 est définie, le type d'exception est défini par :

  1. Exception=Integer;

Si l'option -MC68881 est définie, le type d'exception est défini par :

  1. Exception=LongInt;

Les routines SetException, TestException, SetHalt et TestHalt acceptent toutes des paramètres de type Exception.

Le type RoundDir

Le type RoundDir (Rounding Direction) est défini par :

  1. RoundDir = (ToNearest, Upward, Downward, TowardZero);

Le type RoundDir est utilisé pour déterminer comment les valeurs doivent être arrondies, lorsque l'arrondi devient nécessaire lors d'opérations arithmétiques ou de conversions. La procédure SetRound prend un paramètre de type RoundDir. La fonction GetRound renvoie une valeur de type RoundDir.

Le type RoundPre

Le type RoundPre (Rounding Precision) est défini par :

  1. RoundPre=(ExtPrecision, DblPrecision, RealPrecision);

La précision d'arrondi peut être utilisée pour simuler l'arithmétique avec une précision simple ou double uniquement. La procédure SetPrecision prend un argument de type RoundPre. La fonction GetPrecision renvoie une valeur de type RoundPre.

Le type Environment

Une variable de type Environment contient une valeur représentant les paramètres de l'environnement SANE. Par exemple, un paramètre IEEEDefaultEnv représente le paramètre IEEE par défaut (arrondi au plus proche, arrondi à précision étendue, exceptions supprimées et aucun arrêt défini). Sauf si l'option -MC68881 est définie, le type Environment est défini par :

  1. Environment=Integer;

Vous utilisez une variable de type Environment avec les routines d'accès à l'environnement SetEnvironment, GetEnvironment, ProcEntry et ProcExit.

Si -MC68881 est défini, le type Environment est défini par :

  1. Environment=RECORD
  2.  FPCR:LongInt;
  3.  FPSR:LongInt;
  4. END;

PPCR représente le registre de contrôle à virgule flottante 68881 et FPSR représente son registre d'état à virgule flottante.

Procédures et fonctions numériques

Cette section comprend une description de chacune des procédures et fonctions des bibliothèques SANE. Des informations plus détaillées sont disponibles dans le manuel Apple Numerics.

N'oubliez pas que toute fonction avec un paramètre formel de l'un des types réels peut recevoir une valeur de n'importe quel type réel ou entier. Point flottant. Les paramètres de valeur dans MPW Pascal accepteront les expressions et les variables de l'un des types suivants : Integer, LongInt, Real (Single), Double, Comp ou Extended. Nous abrégeons la liste avec le terme argument numérique dans le texte explicatif ci-dessous.

Conversions entre types binaires numériques

Les bibliothèques SANE contiennent des fonctions convertissant les valeurs numériques (en représentation binaire) aux formats binaires des types Integer, LongInt et Extended.

Les fonctions Num2Integer et Num2LongInt

Function Num2Integer(X:Extended):Integer;
Function Num2LongInt(X:Extended):LongInt;

La fonction Num2Integer prend un paramètre numérique et renvoie un résultat de type Integer. La fonction Num2Longint prend un paramètre numérique et renvoie un résultat de type LongInt. La valeur renvoyée par ces fonctions dépend du sens d'arrondi (défini à l'aide de la procédure SetRound). En utilisant la direction d'arrondi standard, ToNearest, les exemples :

  1. Num2Integer(99.6);
  2. Num2LongInt(99.6);

renvoie la valeur 100,0.

Les Num2Integer et Num2LongInt sont similaires aux fonctions Round et Trunc de MPW Pascal. Cependant, Num2Integer et Num2LongInt prennent en compte le sens d'arrondi actuel. La fonction Round renvoie toujours la valeur du LongInt la plus proche ; la fonction Trunc arrondit toujours vers zéro.

Voici un exemple de la façon dont ces fonctions sont utilisées :

  1. Var
  2.  A:Extended;
  3.  B,C,D:LongInt;
  4. Begin
  5.  A:=99.999;
  6.  B:=Num2Longint(A);
  7.  C:=Round(A);
  8.  D:=Trunc(A)
  9. End;

Une fois ce code exécuté, B et C ont tous deux la valeur 100 et D a la valeur 99.

  1. BEGIN
  2.  A:=99.999;
  3.  SetRound(Downward);
  4.  B:=Num2LongInt(A);
  5.  C:=Round(A);
  6.  D:=Trunc(A)
  7. END;

Avec ce code, cependant, les valeurs de B et D sont 99. Mais la valeur de C est à nouveau 100. Les fonctions Round et Trunc calculent toujours leur valeur de la même manière, quel que soit le sens de l'arrondi.

En utilisant le sens d'arrondi ToNearest, Num2Integer et Num2Longint arrondissent les valeurs à mi-chemin entre deux entiers à l'entier pair le plus proche (comme prescrit par la norme IEEE). Par exemple, Num2Integer(2.5) renvoie deux. La fonction Round arrondit ces valeurs à mi-chemin de zéro. Par exemple, Round(2.5) renvoie trois.

La fonction Num2Extended

Function Num2Extended(X:Extended):Extended;

La fonction Num2Extended peut recevoir n'importe quel paramètre de type réel ou de type entier. Il convertit son paramètre au format Extended. Ceci est utile pour forcer l'arithmétique à virgule flottante lorsque toutes les variables impliquées sont de type entier.

Conversions entre chaînes de caractères décimales et binaires

La bibliothèque SANE comprend la procédure Num2Str et la fonction Str2Num pour convertir les nombres entre les représentations de caractères décimaux ASCII et binaires.

Remarque : Les procédures d'entrée et de sortie MPW Pascal utilisent les routines pour les conversions Pascal d'entrée/sortie entre ASCII décimal et binaire.

La procédure Num2Str

Function Num2Str(f:DecForm;x:Extended;Var S:DecStr);

La procédure Num2Str convertit une valeur numérique x en une chaîne de caractères décimale, renvoyée en s, en utilisant les spécifications de l'enregistrement DecForm f. Voici quelques exemples de la manière dont Num2Str utilise les paramètres lui étant passés pour former une chaîne de caractères :

Dec:Form.Style Dec:Form.Digits x S
FloatDecimal 6 123.45 ' 1.23450e+2'
FloatDecimal 2 123.45 ' 1.2e+2'
FixedDecimal 6 123.45 '123.450000'
FixedDecimal 2 123.45 '123.45'

La fonction Str2Num

Function Str2Num(S:DecStr):Extended;

La fonction Str2Num prend un paramètre de chaîne de caractères décimal (de type DecStr) et le convertit en type Extended.

Fonctions arithmétiques, auxiliaires et élémentaires

La bibliothèque SANE comprend un ensemble de fonctions complétant les fonctions arithmétiques.

La fonction Remainder

Function Remainder(x,y:Extended;Var quo:Integer);

La fonction Remainder renvoie le reste de la division de ses deux paramètres numériques x/y, comme spécifié par la norme IEEE. Cette fonction renvoie un reste exact de la plus petite magnitude possible. Le résultat est calculé sous la forme x-n*y, où n est l'approximation intégrale la plus proche du quotient x/y. Par exemple, Remainder(9,5,q) renvoie -1, car -1*9-2*5.

Le paramètre de la variable entière quo reçoit les 7 bits de poids faible de n comme valeur comprise entre -127 et 127; ceci est utile pour programmer des fonctions, comme les fonctions trigonométriques, nécessitant une réduction de paramètres.

Remarque : N'oubliez pas que l'opérateur Pascal MOD ne peut être utilisé qu'avec des valeurs intégrales. La fonction Remainder peut être utilisée avec des valeurs de type réel ou entier.

La fonction Rint

Function Rint(X:Extended):Extended;

La fonction Rint prend un paramètre numérique et l'arrondit à une valeur entière au format étendu. Notez que toutes les valeurs à virgule flottante suffisamment grandes sont intégrales. Le résultat dépend du sens de l'arrondi, pouvant être modifié à l'aide de la procédure SetRound.

La fonction Scalb

Function Scalb(n:Inteqer;X:Extended):Extended;

La fonction Scalb prend deux paramètres. Le premier est une valeur de type entier ; la seconde est une valeur étendue. La fonction met à l'échelle la valeur Extended par la puissance de deux spécifiée par le paramètre Integer. La valeur 2nx est renvoyée au format Extended.

La fonction Logb

Function Logb(X:Extended):Extended;

La fonction Logb prend un paramètre numérique et renvoie la plus grande puissance de deux ne dépassant pas la grandeur de son paramètre. Par exemple, Logb(-65535) donne 15 car 215 ≤ 65535 < 216.

La fonction CopySign

Function CopySign(X,Y:Extended):Extended;

La fonction CopySign prend des paramètres numériques. Il renvoie une valeur égale au deuxième paramètre, mais avec le signe du premier paramètre. Par exemple, CopySign(2.0,-3.0) donne 3,0. La fonction CopySign renvoie une valeur Extended.

La fonction NextReal

Function NextReal(x,y:Real):Extended;

La fonction NextReal prend deux paramètres réels. Il renvoie la prochaine valeur pouvant être représentée au format réel après le premier paramètre, dans la direction du deuxième paramètre. Il renvoie une valeur Extended.

Remarque : Bien que NextReal, NextDouble et NextExtended puissent accepter n'importe quel paramètre numérique, NextReal convertit en interne ses paramètres en réel, NextDouble en double et NextExtended en étendu.

La fonction NextDouble

Function NextDouble(X,Y:Double):Extended;

La fonction NextDouble prend deux paramètres Double. Il renvoie la valeur suivante pouvant être représentée au format Double après le premier paramètre, dans la direction du deuxième paramètre. Il renvoie une valeur étendue.

La fonction NextExtended

Function NextExtended(X,Y:Extended):Extended;

La fonction NextExtended prend deux paramètres étendus. Il renvoie la valeur suivante pouvant être représentée au format étendu après le premier paramètre, dans la direction du deuxième paramètre. Il renvoie une valeur étendue.

La fonction Log2

Function Log2(X:Extended):Extended;

La fonction Log2 prend un paramètre numérique et renvoie le logarithme base 2 de son paramètre au format étendu.

La fonction Ln1

Function Ln1(X:Extended):Extended;

La fonction Ln1 prend un paramètre numérique et renvoie le logarithme base-e de un plus le paramètre : Ln(1+x). Il renvoie une valeur Extended. Pour x proche de zéro, Ln1(x) est plus précis que Ln(1.0+x).

La fonction Exp2

Function Exp2(X:Extended):Extended;

La fonction Exp2 prend un paramètre numérique et renvoie deux élevés à la puissance du paramètre : 2x. Il renvoie une valeur Extended.

La fonction Exp1

Function Exp1(X:Extended):Extended;

La fonction Exp1 prend un paramètre numérique et renvoie ex-1. Il renvoie une valeur Extended. Pour x proche de zéro, Exp1(X) est plus précis que Exp(x)-1.0.

La fonction XpwrI

Function XpwrI(x:Extended;i:Integer):Extended;

La fonction XpwrI prend un paramètre numérique et un paramètre entier. Il renvoie la valeur de son premier paramètre élevé à la puissance spécifiée par le paramètre Integer : xi. Il renvoie une valeur Extended.

La fonction XpwrY

Function XpwrY(x,y:Extended):Extended;

La fonction XpwrY prend deux paramètres numériques. Il renvoie la valeur du premier paramètre, élevée à la puissance spécifiée par le deuxième paramètre : xy. Il renvoie une valeur Extended.

Fonctions financières

Le SANE propose deux fonctions pouvant être utilisées dans les applications financières : la fonction composée et la fonction Annuity.

La fonction Compound

Function Compound(r,n:Extended):Extended;

La fonction Compound prend deux paramètres numériques. Le premier paramètre spécifie le taux d'intérêt ; la seconde précise le nombre de périodes composées. Il renvoie (1+r)n, correspondant au principal plus les intérêts composés courus sur un investissement initial d'une unité. Il renvoie une valeur Extended.

La fonction Annuity

Function Annuity(r,n:Extended):Extended;

La fonction Annuity prend deux paramètres numériques. Le premier paramètre spécifie le taux d'intérêt ; la seconde précise le nombre de périodes. La rente renvoie (1-(1+r)-n)/r, étant le facteur de valeur actuelle d'une rente ordinaire. Il renvoie une valeur étendue. Voici un exemple de la façon dont la fonction Rente peut être utilisée :

  1. Program _Loan;
  2.  
  3. Uses SANE;
  4.  
  5. Var
  6.  Loan,Payment,Interest,Periods:Extended;
  7.  
  8. BEGIN
  9.  WriteLn('Montant du prêt: ');
  10.  ReadLn(Loan);
  11.  Writeln('Taux d''intérêt annuel (Entrez sous forme décimale.) :');
  12.  ReadLn(Interest);
  13.  WriteLn('Nombre d''années:');
  14.  ReadLn(Periods);
  15.  Payment:= Loan/Annuity(Interest/12,Periods*12);
  16.  Write('Votre paiement est : ');
  17.  Write(Payment:8:2);
  18. END.

Dans cet exemple, étant donné un montant de prêt de 120 000 $ et un taux d'intérêt de 0,1075 sur 30 ans, le paiement mensuel sera de 1 120,18 $.

Fonctions trigonométriques

Le MPW Pascal inclut les fonctions prédéfinies Sin, Cos et Arctan. De plus, la bibliothèque SANE fournit la fonction Tan.

La fonction Tan

Function Tan(X:Extended):Extended;

La fonction Tan renvoie la tangente d'un paramètre numérique. Notez que le paramètre doit être exprimé en radians. La fonction Tan renvoie une valeur Extended.

Routines transcendantales supplémentaires

Le MPW Pascal prédéfinit ces neuf routines lorsque l'option -MC68881 du compilateur est utilisée. Ces routines ne font pas partie de l'interface SANE et sont indisponibles sans l'option -MC68881.

La fonction Arctanh

Function Arctanh(X:Extended):Extended;

La fonction Arctanh renvoie l'arctangente hyperbolique d'un paramètre numérique. La fonction Arctanh renvoie une valeur étendue.

La fonction Cosh

Function Cosh(X:Extended):Extended;

La fonction Cosh renvoie le cosinus hyperbolique d'un paramètre numérique. La fonction Cosh renvoie une valeur Extended.

La fonction Sinh

Function Sinh(X:Extended):Extended;

La fonction Sinh renvoie le sinus hyperbolique d'un paramètre numérique. La fonction Sinh renvoie une valeur Extended.

La fonction Tanh

Function Tanh(X:Extended):Extended;

La fonction Tanh renvoie la tangente hyperbolique d'un paramètre numérique. La fonction Tanh renvoie une valeur Extended.

La fonction Log10

Function Log10(X:Extended):Extended;

La fonction Log10 renvoie le logarithme base 10 d'un paramètre numérique. La fonction Log10 renvoie une valeur Extended.

La fonction Exp10

Function Exp10(X:Extended):Extended;

La fonction Exp10 renvoie dix élevé à la puissance d'un paramètre numérique : 10x. La fonction Exp10 renvoie une valeur Extended.

La fonction Arccos

Function Arccos(X:Extended):Extended;

La fonction Arccos renvoie la valeur principale, en radians, de l'arccosinus d'un paramètre numérique. La fonction Arccos renvoie une valeur Extended.

La fonction ArcSin

Function Arcsin(X:Extended):Extended;

La fonction Arcsin renvoie la valeur principale, en radians, de l'arc sinus d'un paramètre numérique. La fonction Arcsin renvoie une valeur Extended.

La procédure SinCos

Procedure SinCos(Var S,C:Extended;X:Extended);

La procédure SinCos définit simultanément la variable S sur Sin(X) et la variable C à Cos(X). Le paramètre X est un paramètre numérique. La procédure SinCos est plus rapide que les appels de fonctions séparés à Sin et Cos.

Fonctions d'enquête

Le SANE comprend plusieurs fonctions vous permettant de déterminer la classe d'une valeur numérique. Le résultat de chacune de ces fonctions est du type NumClass, décrit ci-dessus. De plus, ils incluent une fonction renvoyant le signe d'un paramètre numérique.

La fonction ClassReal

Function ClassReal(Var X:Extended):NumClass;

La fonction ClassReal détermine la classe numérique d'un paramètre numérique comme si le paramètre était converti au format Real. Par exemple :

  1. Var
  2.  a,b:NumClass;
  3.  
  4. BEGIN
  5.  a:=ClassReal(1);
  6.  b:=ClassReal(1e-310);
  7. END.

Le premier appel de fonction renvoie NormalNum, le code d'un nombre normalisé. Le deuxième appel renvoie ZeroNum, le code de zéro (car 1e-310 arrondit à +0 dans le format Real).

La fonction ClassDouble

Function ClassDouble(X:Double):NumClass;

La fonction ClassDouble détermine la classe numérique d'un paramètre numérique comme si le paramètre était converti en un format double. Le résultat est de type NumClass. Par exemple :

  1. Var
  2.  a,b:NumClass;
  3.  
  4. BEGIN
  5.  a:=ClassDouble(0.0/0.0);
  6.  b:=ClassDouble(1e-310);
  7. END.

Le premier exemple renvoie QNaN, le code d'un NaN silencieux. Le deuxième exemple renvoie DenormalNum, le code d'un nombre dénormalisé (car 1e-310 est dénormalisé au format double).

La fonction ClassExtended

Function ClassExtended(X:Extended):NumClass;

La fonction ClassExtended détermine la classe numérique d'un paramètre numérique comme si le paramètre était converti dans un format étendu. Le résultat est de type NumClass. Par exemple :

  1. Var
  2.  a,b:NumClass;
  3. BEGIN
  4.  a:=ClassExtended(1/0);
  5.  b:=ClassExtended(E-310);
  6. END.

Le premier exemple renvoie Infinite, le code des infinis. Le deuxième exemple renvoie NormalNum, le code d'un nombre normalisé.

La fonction ClassComp

Function ClassComp(x:Comp):NumClass;

La fonction ClassComp détermine la classe numérique de son paramètre numérique comme si le paramètre était converti au format comp. Le résultat est de type NumClass. Par exemple :

  1. Var
  2.  a,b:NumClass;
  3. BEGIN
  4.  a:=ClassComp(1);
  5.  b:=ClassComp(0.1);
  6. END.

Le premier exemple renvoie NormalNum, le code d'un nombre normal. Le deuxième exemple renvoie zeroNum, le code de zéro. (N'oubliez pas que comp entrepose les valeurs intégrales.)

La fonction SigNum

Function SignNum(x:Extended):Integer;

La fonction SignNum prend un paramètre numérique et renvoie une valeur entière indiquant le signe du paramètre. La valeur renvoyée est un si le signe du paramètre est négatif, zéro si le signe du paramètre est positif.

La fonction RandomX

Function RandomX(Var x:Extended):Extended;

La fonction RandomX prend un paramètre variable de type Extended devant contenir une valeur intégrale comprise entre 1 ≤ x ≤ 231-2. Il renvoie le nombre aléatoire suivant (au format étendu) en séquence dans le même intervalle. Le paramètre variable est mis à jour avec la valeur renvoyée. RandomX utilise cet algorithme :

NewX = (75*OldX) MOD (231-1)

La fonction NaN

Function Nan(x:Integer):Extended;

La fonction Nan prend un paramètre entier et renvoie un NaN, au format étendu, associé au code donné en paramètre.

La fonction Relation

Function Relation(x,y:Extended):RelOp;

La fonction Relation prend deux paramètres numériques et renvoie une valeur de type Relop. La valeur renvoyée spécifie la relation entre les deux paramètres. Par exemple, Relation(0,1,NaN(0)) renvoie un ordre non ordonné, car toutes les comparaisons impliquant des NaN sont non ordonnées. La relation (1, 3, 9) renvoie LessThan.

Procédures et fonctions d'accès à l'environnement

Les routines d'accès environnemental SANE vous permettent de déterminer comment les calculs doivent être effectués et comment répondre à des conditions exceptionnelles. L'environnement est constitué de :

Le sens de l'arrondissement

Le sens de l'arrondi peut être défini de quatre manières :

La direction d'arrondi par défaut est ToNearest. Vous pouvez découvrir quelle est la direction d'arrondi actuelle en utilisant la fonction GetRound. Vous pouvez modifier le sens de l'arrondi à l'aide de la procédure d'arrondi définie.

La fonction GetRound

Function GetRound:RoundDir;

La fonction GetRound renvoie la direction d'arrondi actuelle sous la forme d'une valeur de type RoundDir.

La procédure SetRound

Procedure SetRound(r:RoundDir);

La procédure SetRound prend un paramètre de type RoundDir. La procédure définit la direction d'arrondi effective sur celle indiquée par le paramètre. Par exemple, le code ci-dessous enregistre le sens d'arrondi actuel, calcule une fonction en utilisant l'arrondi TowardZero et restaure enfin le sens d'arrondi enregistré.

  1. Var
  2.  R:RoundDir;
  3.  X,Y:Extended;
  4. BEGIN
  5.  R:=GetRound;
  6.  SetRound(TowardZero);
  7.  Y:=f(X);
  8.  SetRound(R);
  9. END.

Précision d'arrondi

Vous souhaiterez peut-être utiliser SANE pour effectuer des calculs et simuler les résultats que vous obtiendriez si vous utilisiez un système ne fournissant pas d'arithmétique de précision étendue. Normalement, tous les calculs à virgule flottante MPW Pascal renvoient des résultats arrondis à une précision et un intervalle étendues. Cependant, la précision d'arrondi peut être réglée sur une précision et un intervalle simples ou doubles. Les résultats seront toujours renvoyés au format étendu. Il n'y a aucun avantage en termes de performances à définir une précision d'arrondi simple ou double. Vous pouvez accéder à la précision de l'arrondi à l'aide de la procédure SetPrecision et de la fonction GetPrecision.

La fonction GetPrecision

Function GetPrecision:RoundPre;

La fonction GetPrecision renvoie une valeur de type RoundPre, indiquant la précision d'arrondi actuelle.

La procédure SetPrecision

Procedure SetPrecision(p:RoundPre);

La procédure SetPrecision prend un paramètre étant une variable de type RoundPre, indiquant la précision d'arrondi souhaitée.

Des exceptions

Lorsque -MC68881 n'est pas défini, les résultats exceptionnels résultant de calculs numériques se répartissent en cinq catégories. Le fichier SANE.p dans PInterfaces définit une constante pour chaque type d'exception, comme indiqué dans le tableau suivant :

Exception Valeur de la constante Description Exemple
Invalid 1 Opération non significative - résultat NaN Sqrt(-1)
Underflow 2 Précision perdue - résultat trop petit 2-16383/3
Overflow 4 Résultat trop grand pour la représentation numérique 216384
DivByZero 8 Division d'un nombre différent de zéro par zéro 1/0
Inexact 16 Le résultat arrondi n'est pas le même que le résultat mathématique exact 1/3

Les exceptions indiquées dans le tableau précédent se produisent dans les conditions suivantes :

Le tableau suivant répertorie les résultats exceptionnels pouvant se produire lorsque -MC68881 est défini. Le préfixe Cur représente l'exception actuelle. Ces huit valeurs correspondent à l'octet d'état d'exception 68881.

Exception Valeur constante
Inexact 8
DivByZero 16
Underflow 32
Overflow 64
Invalid 128
CurInex1 256
CurInex2 512
CurDivByZero 1024
CurUnderflow 2048
CurOverflow 4096
CurOpError 8192
CurSigNaN 16384
CurBSonUnor 32768

La procédure SetException

Procedure SetException(e:Exception;b:Boolean);

La procédure SetException prend un paramètre de type Exception et un deuxième paramètre de type Boolean. Si le deuxième paramètre est vrai, la procédure signale les exceptions codées dans son premier paramètre. Si le deuxième paramètre est faux, il efface les indicateurs d'exception spécifiés par le premier paramètre. Par exemple :

  1. SetException(Overflow+Inexact,True);

signale les exceptions Overflow et Inexact. Si l'arrêt en cas de débordement ou Inexact était défini, cette instruction arrêterait le programme.

La fonction TestException

Function TestException(e:Exception):Boolean;

La fonction TestException prend un paramètre de type Exception et renvoie une valeur booléenne indiquant si l'une des exceptions codées dans son paramètre est définie ou non.

Suite à l'instruction SetException ci-dessus, l'instruction :

  1. TestException(OverFlow+Invalid);

reviendrait true.

Utiliser des conditions exceptionnelles pour arrêter un programme

L'environnement SANE inclut un paramètre d'arrêt pour chacune des exceptions déterminant si l'occurrence de l'exception arrête le programme. Par défaut, le MPW Pascal adhère à la norme IEEE en initialisant tous les arrêts à effacé (off).

Vous pouvez accéder aux paramètres d'arrêt à l'aide de la fonction TestHalt et de la procédure SetHalt.

La fonction TestHalt

Function TestHalt(e:Exception):Boolean;

La fonction TestHalt prend un paramètre de type Exception et renvoie une valeur booléenne. Si l'un des arrêts indiqués par le paramètre Exception est défini, la fonction renvoie true ; sinon, il renvoie false.

La procédure SetHalt

Procedure SetHalt(e:Exception;b:Boolean);

La procédure SetHalt prend deux paramètres. Le premier est de type Exception. Cela indique les exceptions pour lesquelles vous souhaitez arrêter votre programme. Le deuxième paramètre est de type Boolean. Si la valeur du paramètre Boolean est true, les occurrences des exceptions indiquées entraîneront l'arrêt de votre programme. Si c'est False, votre programme continuera à s'exécuter lorsque ces exceptions se produiront.

Arrêts et le 68881

Lorsque l'option -MC68881 est définie, les arrêts en virgule flottante sont générés par le 68881 et non par Pack4. Les anciennes sources d'un gestionnaire d'arrêt ne fonctionneront plus lorsqu'elles seront compilées avec l'ensemble -MC68881.

Pour plus de détails sur les gestionnaires d'arrêt SANE compatibles avec Pack4. La prise en charge suivante pour 68881 arrêts et interruptions a été ajoutée au fichier SANE.p :

  1. Type
  2.  TrapVector=Record
  3.   Unordered:LongInt;
  4.   Inexact:LongInt;
  5.   DivByZero:LongInt;
  6.   Underflow:LongInt;
  7.   OpError:LongInt;
  8.   Overflow:LongInt;
  9.   SigNaN:LongInt;
  10.  End;
  11.  
  12. Procedure GetTrapVector(Var Traps:TrapVector); { Pièges <-- vecteurs de pièges FPCP }
  13. Procedure SetTrapVector(Traps: TrapVector); { Vecteurs de pièges FPCP <-- Pièges }

La définition du type TrapVector et ses procédures associées, GetTrapVector et setTrapVector, vous donnent accès à ces vecteurs d'exceptions 68020 gérant les exceptions 68881 à virgule flottante. Les procédures permettant de définir et d'obtenir des arrêts, des exceptions et des environnements fonctionnent comme lorsque -MC68881 n'est pas défini ; ils ne diffèrent que par les types de données utilisés comme paramètres.

Enfin, contrairement au mécanisme d'arrêt Pack4, le 68881 prend en charge le mécanisme de piège recommandé par l'IEEE. Le mot piège apparaît dans les noms ci-dessus pour souligner cette différence. Les pièges IEEE faussent parfois l'exposant des résultats à virgule flottante ; dans certains cas, les exceptions sont définies différemment lorsque les interruptions sont activées, et la pile transmise à un gestionnaire d'interruptions est configurée différemment par le mécanisme d'interruption 68881.

Sauvegarde et restauration des paramètres d'environnement

L'ensemble de l'environnement SANE (direction d'arrondi, précision d'arrondi, indicateurs d'exception et paramètres d'arrêt) peut être codé dans une valeur de type Environment. Les procédures décrites ci-dessous accèdent à l'environnement SANE actuel dans son ensemble. Ils sont utiles pour gérer l'environnement afin que les routines s'exécutent avec les environnements dont elles ont besoin et pour contrôler les informations d'exception transmises entre les routines.

La procédure GetEnvironment

Procedure GetEnvironment(Var e:Environment);

La procédure GetEnvironment prend un paramètre de type Environment comme paramètre de variable et affecte les paramètres actuels de l'environnement à cette variable.

Lorsque votre programme démarre, l'environnement reflétera les valeurs par défaut de MPW Pascal :

La procédure SetEnvironment

Procedure SetEnvironment(e:Environment);

La procédure SetEnvironment prend un paramètre de type Environment. Il définit l'environnement à virgule flottante sur celui codé dans son paramètre. Pour réinstaller l'environnement par défaut, utilisez l'instruction :

  1. SetEnvironment(IEEEDefaultEnv);

La procédure suivante garantit qu'il s'exécutera dans l'environnement par défaut IEEE, sans affecter l'environnement de son appelant :

  1. Procedure P;
  2. Var
  3.  SaveEnv:Environment;
  4. BEGIN
  5.  GetEnvironment(SaveEnv);
  6.  SetEnvironment(IEEEDefaultEnv);
  7.  SetEnvironment(SaveEnv);
  8. END;

Notez que le type Environment n'est pas le type entier lorsque l'option -MC68881 du compilateur est appelée, donc l'ancienne utilisation, SetEnvironment(0), ne fonctionnera plus avec cette option. Pour des raisons de compatibilité, SetEnvironment(IEEEDefaultEnv) fonctionne correctement quel que soit le paramètre de l'option -MC68881.

La procédure ProcEntry

Procedure ProcEntry(Var e:Environment);

La procédure ProcEntry enregistre l'environnement actuel (la direction de l'arrondi, la précision de l'arrondi, les indicateurs d'exception et les paramètres d'arrêt) dans la variable d'environnement transmise à la procédure, puis définit l'environnement sur les valeurs par défaut IEEE. L'instruction ProcEntry(e) est équivalente à :

  1. GetEnvironment(e);
  2. SetEnvironment(IEEEDefaultEnv);

La procédure ProcExit

Procedure ProcExit(e:Environment);

La procédure ProcExit prend un paramètre de type Environment. Il enregistre temporairement les indicateurs d'exception actuels, définit l'environnement effectif comme étant celui codé dans son paramètre, puis signale les exceptions temporairement enregistrées.

ProcEntry et ProcExit peuvent être utilisés dans des routines pour masquer sélectivement les exceptions suspectes des appels de la routine. Par exemple :

  1. Function Arccos(X:Extended):Extended;
  2. Var
  3.  e:Environment;
  4. Begin
  5.  ProcEntry(e);
  6.  Arccos:=2.0*Arctan(Sqrt(1.0-x)/(1.0+x));
  7.  SetException(DivByZero,False);
  8.  ProcExit(e);
  9. End;

ProcEntry(e) enregistre l'environnement de l'appelant dans e et définit les valeurs par défaut IEEE afin que les exceptions ne puissent pas interrompre la routine. Si x = -1, le calcul du côté droit de l'affectation à ArcCos signalera DivByZero, même si ArcCos se verra attribuer la valeur correcte, PI. SetException(DivByZero,False) efface l'indicateur DivByZero afin que l'appelant ne le voie jamais. Si x > 1 ou x < -1, le calcul d'Arccos signalera de manière appropriée Invalid. La procédure ProcExit renverra Invalid après la restauration de l'environnement de l'appelant, donc si l'environnement de l'appelant demande des arrêts sur invalide, l'arrêt se produira.

Prise en charge du 68881

La liste suivante résume la prise en charge de MPW Pascal pour le coprocesseur à virgule flottante 68881. Des informations détaillées sur SANE et la programmation du 68881 sont fournies dans les sections ci-dessous.

SANE et le 68881

Le SANE est l'environnement numérique d'Apple. Il s'agit d'un surensemble de valeurs numériques de la norme IEEE 754. Tous les ordinateurs Apple et la plupart des langages de programmation Apple intègrent SANE. Dans la famille Macintosh, SANE est contenu dans la ROM système sous forme de Pack4 et de Pack5. Le MPW Pascal gère l'arithmétique à virgule flottante en émettant du code pour appeler les Packs. La virgule flottante dans la famille Macintosh est identique en termes de précision et, à l'exception du Macintosh II, à peu près aussi rapide.

Les performances en virgule flottante sur le Macintosh II sont d'un ordre de grandeur plus rapides que sur le Macintosh Plus car Pack4 et Pack5 (dans la ROM du Macintosh II) tirent parti du coprocesseur à virgule flottante 68881 chaque fois que cela est possible. Le 68881 est une puce à virgule flottante très rapide, entièrement conforme à la norme IEEE 754 et, comme SANE, possède plusieurs extensions intégrées à la norme IEEE. Pour les performances en virgule flottante les plus rapides possibles, MPW Pascal peut utiliser directement le 68881, évitant ainsi les appels à Pack4 et Pack5.

L'option de ligne de commande -MC68881 indique au compilateur d'utiliser les appels 68881 pour les opérations arithmétiques de base (addition, soustraction, multiplication, racine carrée, reste, comparaison et conversions de format binaire-binaire). Lorsque vous invoquez cette option, les trois effets suivants se produisent :

Les valeurs des résultats seront identiques à celles reçues sans l'option -MC68881. Une autre option, écrite -d Elems88l=true, demande au compilateur d'utiliser les appels 68881 pour toutes les 68881 fonctions transcendantales (logarithmes, exponentielles, trigonométriques et trigonométriques hyperboliques). Cette option n'a aucune signification sauf si l'option -MC68881 est déjà appelée ; de plus, il a deux effets importants :

En savoir plus sur le 68881

Le Pascal vous permet de redéfinir toutes les fonctions, procédures et types prédéfinis. L'utilisation de -d Elems881=true, décrite ci-dessus, contrôle simplement la redéfinition de plusieurs routines intégrées au compilateur. SANE.p dans le dossier PInterfaces contient des déclarations de 19 fonctions transcendantales prédéfinies par le compilateur. Les fonctions transcendantales se répartissent en trois groupes :

Lorsque -d Elems881=-true est défini (et que -MC68881 est invoqué), le compilateur effectue des appels directs 68881 pour toutes les fonctions prédéfinies Pascal, les fonctions SANE et les fonctions supplémentaires répertoriées ci-dessus. Sinon, les déclarations des fonctions prédéfinies Pascal et des fonctions SANE sont vues par le compilateur dans SANE.p, les appels directs à ces fonctions ne sont pas effectués et le compilateur génère des appels aux versions de ces routines trouvées dans SANELib881.o. En effet, SANE.p indique au compilateur d'appeler la version de ces fonctions ainsi, est fourni au moment du lien dans le fichier SANELib881.o du dossier {Plibraries}. SANELib881.o, à son tour, appelle les Pack5 dans la ROM pour plus de précision et de compatibilité. (Lorsque l'option -MC68881 est définie, il crée un lien uniquement avec SANELib881.o ; sinon, il crée un lien avec SANELib.o.)

Usage des registres

Le 68881 ajoute huit nouveaux registres, appelés FP0,...,FP7, aux familiers D0,...,D7 et A0,...,A7 du 68020. Les registres FP ont une largeur de 96 bits et sont conçus pour contenir données de précision étendue. Le Pascal optimise l'utilisation de ces registres pour les variables et pour l'évaluation des expressions. Le Pascal place les variables dans FP4, ..., FP7 et alloue FP0, ..., FP3 comme registres de travail.

Par exemple, toutes les expressions à virgule flottante, telles que le côté droit de :

  1. x:=3*y+6;

sont évalués dans les registres FP. Si x et y sont des variables de type étendu, le compilateur peut également les allouer à des registres, améliorant encore davantage les performances.

Conversion entre formats Extended dans les programmes à monde mixte

Apple recommande de compiler tous vos fichiers programme soit avec l'option -MC68881 jamais définie, soit avec cette option toujours définie. La construction d'un programme avec des paramètres mixtes de cette option provoque des problèmes des manières suivantes :

Si vous devez mélanger des fichiers contenant différents formats étendus, une prise en charge limitée est proposée pour résoudre le problème lié à l'appel d'une fonction possédant l'autre format étendu. SANE.p définit les fonctions suivantes pour convertir entre les formats étendus 96 bits et 80 bits :

Function X96to80(X:Extended96):Extended;
Function X80to96(X:Extended):Extended96;

pour une utilisation dans le monde 80 bits, et :

Function X96to80(X:Extended):Extended80;
Function X80to96(X:Extended80):Extended96;

pour une utilisation dans le monde 96 bits.

Les types :

  1. Type
  2.  Extended80=ARRAY[0..4] of Integer;

et :

  1. Type
  2.  Extended96=Array[0..5] of Integer;

ne sont utiles que dans ces routines de transfert - vous ne pouvez pas faire d'arithmétique avec eux. Ils ne sont pas compris par le compilateur comme étant équivalents au type étendu.

Par exemple, si :

  1. Function foo(X:Extended):Extended;

est compilé avec l'ensemble d'options -MC68881 (de sorte que pour cette fonction, le type Extended a une largeur de 96 bits), alors pour appeler foo depuis un monde 80 bits, vous feriez :



Dernière mise à jour : Vendredi, le 28 juin 2024