v0.2.17
This commit is contained in:
@@ -1,32 +1,29 @@
|
||||
# Saselang — Annexe A — Matrice des conversions numériques
|
||||
|
||||
**Version documentaire : 0.2.12. Statut : inventaire de conception Core, destiné à devenir normatif après validation.**
|
||||
**Version documentaire : 0.2.17. Statut : inventaire de conception Core destiné à devenir normatif après validation.**
|
||||
|
||||
Cette annexe est le listing exhaustif de travail des conversions numériques Core.
|
||||
Son objectif est d'énumérer le maximum de conversions numériques sémantiquement distinctes sans introduire d'alias ou de doublons inutiles.
|
||||
Cette annexe inventorie les conversions numériques Core sémantiquement distinctes sans créer d'alias ou de doublons inutiles.
|
||||
|
||||
## A.1. Répartition des responsabilités
|
||||
|
||||
Les conversions numériques sont exposées comme capacités de l'API Core des primitives. Elles ne deviennent pas chacune une construction grammaticale du compilateur.
|
||||
Les conversions numériques sont des capacités de l'API Core des primitives, pas des constructions grammaticales distinctes.
|
||||
|
||||
```text
|
||||
Bible langage / compilateur
|
||||
définit les règles de typage, d'appel, d'intrinsic, de target et de lowering
|
||||
définit typage, contrats, faults, targets et lowering
|
||||
|
||||
Core
|
||||
expose les membres numériques concrets
|
||||
ex. int32::tryToInt8(), float64::tryRoundToFloat32()
|
||||
ex. int32::toInt8(), float64::roundToFloat32()
|
||||
|
||||
Annexe Core
|
||||
liste exhaustivement les opérations disponibles par paire de types
|
||||
liste les opérations disponibles par paire de types
|
||||
|
||||
Compilateur / Sase IR / backend
|
||||
valide et abaisse l'opération Core sans que chaque nom devienne de la grammaire
|
||||
valide et abaisse les opérations Core
|
||||
```
|
||||
|
||||
Une capacité Core peut être conditionnée par un target ou une plateforme lorsque cela est réellement nécessaire. L'absence d'une capacité demandée doit être diagnostiquée à la compilation pour le target choisi, et non découverte tardivement dans le backend.
|
||||
|
||||
Les conversions numériques fondamentales entre primitives standard sont destinées à constituer le socle Core commun ; le mécanisme de capacités existe surtout pour les opérations qui ne peuvent raisonnablement pas être garanties partout.
|
||||
Si les types source et destination sont supportés par un target, les conversions fondamentales non redondantes sont Core-required. Une implémentation logicielle conforme est admise lorsqu'une instruction matérielle n'existe pas.
|
||||
|
||||
## A.2. Règle de non-redondance
|
||||
|
||||
@@ -34,68 +31,86 @@ Une variante n'existe que si elle apporte une sémantique observable différente
|
||||
|
||||
Exemple :
|
||||
|
||||
```saselang
|
||||
```text
|
||||
int8 value = ...;
|
||||
int32 larger = value::toInt32();
|
||||
```
|
||||
|
||||
Puisque toutes les valeurs `int8` sont représentables exactement dans `int32`, les formes suivantes n'ont aucune raison d'exister :
|
||||
Toutes les valeurs `int8` sont exactement représentables dans `int32`; il n'existe donc pas de variantes inutiles `saturateToInt32()` ou `wrapToInt32()`.
|
||||
|
||||
Pour `int32 -> int8`, les trois contrats suivants sont distincts :
|
||||
|
||||
```text
|
||||
tryToInt32()
|
||||
saturateToInt32()
|
||||
wrapToInt32()
|
||||
toInt8() // exact, peut fault OutOfRange
|
||||
saturateToInt8()
|
||||
wrapToInt8()
|
||||
```
|
||||
|
||||
En revanche, pour `int32 -> int8`, `tryToInt8()`, `saturateToInt8()` et `wrapToInt8()` ont trois contrats différents et peuvent coexister.
|
||||
|
||||
|
||||
Une règle de composition complète cette non-redondance :
|
||||
Règle de composition :
|
||||
|
||||
> Deux opérations ne sont fusionnées dans un même nom que si leur séparation en opérations Core successives modifierait la sémantique, perdrait de l'information ou empêcherait d'exprimer le même contrat.
|
||||
|
||||
Ainsi `value::floor()::tryToInt32()` rend inutile un alias `tryFloorToInt32()` si les deux formes sont strictement équivalentes.
|
||||
Ainsi :
|
||||
|
||||
## A.3. Nomenclature générale
|
||||
```text
|
||||
value::floor()::toInt32()
|
||||
```
|
||||
|
||||
rend inutile un alias `floorToInt32()` si les deux formes sont strictement équivalentes.
|
||||
|
||||
## A.3. Canal d'échec V1
|
||||
|
||||
Les anciennes variantes `try... -> Result<T,NumericConversionError>` ne font plus partie de la matrice canonique uniquement pour transporter un échec de conversion.
|
||||
|
||||
La conversion directe retourne la destination attendue et peut déclarer :
|
||||
|
||||
```text
|
||||
faults NumericConversionFault
|
||||
```
|
||||
|
||||
lorsque sa précondition runtime n'est pas totale.
|
||||
|
||||
`NumericConversionFault` est unchecked et capturable. Une API spécialisée peut toujours choisir explicitement `Result` si son domaine veut représenter l'échec comme une valeur normale, mais cela ne crée pas une seconde famille automatique `try...` dans le Core numérique.
|
||||
|
||||
## A.4. Nomenclature générale
|
||||
|
||||
| Code | Famille | Contrat |
|
||||
|---|---|---|
|
||||
| `T` | `toTarget()` | Exacte et totale pour toutes les valeurs valides du type source. |
|
||||
| `E` | `tryToTarget()` | Exacte pour la valeur courante ; retourne `Err` si l'exactitude ou la représentabilité échoue. |
|
||||
| `R` | `roundToTarget()` | Perte de précision explicitement acceptée ; conversion totale pour cette paire de types. |
|
||||
| `TR` | `tryRoundToTarget()` | Arrondi explicitement accepté, mais la valeur peut être hors du domaine destination. |
|
||||
| `S` | `saturateToTarget()` | Conversion totale par saturation lorsqu'aucun arrondi supplémentaire n'est nécessaire. |
|
||||
| `SR` | `saturatingRoundToTarget()` | Arrondi canonique + saturation explicites pour une destination flottante lorsque les deux peuvent être nécessaires. |
|
||||
| `W` | `wrapToTarget()` | Conversion entière modulo `2^N`, avec interprétation selon le type entier destination. |
|
||||
| `E` | `toTarget()` | Exacte pour la valeur courante ; `faults NumericConversionFault` si impossible. |
|
||||
| `R` | `roundToTarget()` | Perte de précision explicitement acceptée ; totale pour cette paire. |
|
||||
| `FR` | `roundToTarget()` | Arrondi accepté ; peut fault si la valeur est hors du domaine destination. |
|
||||
| `S` | `saturateToTarget()` | Saturation explicite lorsqu'aucun arrondi supplémentaire n'est nécessaire. |
|
||||
| `SR` | `saturatingRoundToTarget()` | Arrondi canonique + saturation explicites. |
|
||||
| `W` | `wrapToTarget()` | Conversion entière modulo `2^N`. |
|
||||
| `—` | aucune | Même type ou opération sans sémantique distincte utile. |
|
||||
|
||||
`NumericConversionError` est retenu comme nom de travail Core. Il pourra être renommé avant stabilisation de la spécification si nécessaire.
|
||||
Aucune de ces opérations n'autorise une conversion implicite entre deux valeurs déjà typées.
|
||||
|
||||
Les formes `try...` retournent conceptuellement :
|
||||
|
||||
```saselang
|
||||
Result<Target, NumericConversionError>
|
||||
```
|
||||
|
||||
Aucune de ces opérations n'autorise une conversion implicite entre deux variables déjà typées.
|
||||
|
||||
## A.4. Flottants : hypothèses de représentation
|
||||
## A.5. Flottants : hypothèses de représentation
|
||||
|
||||
| Type | Précision significative `p` | Exposant maximal fini |
|
||||
|---|---|---|
|
||||
|---|---:|---:|
|
||||
| `float16` | 11 bits | 15 |
|
||||
| `float32` | 24 bits | 127 |
|
||||
| `float64` | 53 bits | 1023 |
|
||||
| `float128` | 113 bits | 16383 |
|
||||
|
||||
Les conversions avec arrondi utilisent par défaut la règle canonique **round to nearest, ties to even**. Cette règle ne dépend ni du linter, ni du profil, ni du backend.
|
||||
Les conversions avec arrondi utilisent la règle canonique **round to nearest, ties to even**. Cette règle ne dépend ni du linter, ni du profil, ni du backend.
|
||||
|
||||
## A.5. Entier -> entier
|
||||
## A.6. Entier -> entier
|
||||
|
||||
Légende :
|
||||
|
||||
- `T` = `toTarget()` uniquement ;
|
||||
- `E+S+W` = `tryToTarget()` + `saturateToTarget()` + `wrapToTarget()`.
|
||||
```text
|
||||
T
|
||||
toTarget() total
|
||||
|
||||
E+S+W
|
||||
toTarget() faults OutOfRange
|
||||
saturateToTarget()
|
||||
wrapToTarget()
|
||||
```
|
||||
|
||||
| Source \ Destination | int8 | int16 | int32 | int64 | int128 | int256 | uint8 | uint16 | uint32 | uint64 | uint128 | uint256 |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
@@ -114,95 +129,104 @@ Légende :
|
||||
|
||||
Règles :
|
||||
|
||||
- si le domaine source est entièrement inclus dans le domaine destination, seule la forme `to...` existe ;
|
||||
- sinon `tryTo...` effectue une conversion exacte conditionnelle ;
|
||||
- `saturateTo...` borne à `Target::Min` / `Target::Max` ; pour un signé vers non signé, toute valeur négative sature à `0` ;
|
||||
- `wrapTo...` utilise une définition mathématique modulo `2^N`, indépendante de la représentation machine du backend ;
|
||||
- domaine source entièrement inclus -> `to...` total ;
|
||||
- sinon `to...` reste exact mais peut produire `OutOfRange` ;
|
||||
- `saturateTo...` borne à `Target::Min` / `Target::Max`, avec `0` pour un négatif vers non signé ;
|
||||
- `wrapTo...` utilise une définition mathématique modulo `2^N` ;
|
||||
- aucun wrapping ni saturation n'est implicite.
|
||||
|
||||
## A.6. Entier -> flottant
|
||||
## A.7. Entier -> flottant
|
||||
|
||||
Légende :
|
||||
|
||||
- `T` = `toFloatXX()` uniquement ;
|
||||
- `E+R` = `tryToFloatXX()` + `roundToFloatXX()` ;
|
||||
- `E+TR+SR` = `tryToFloatXX()` + `tryRoundToFloatXX()` + `saturatingRoundToFloatXX()`.
|
||||
```text
|
||||
T
|
||||
toFloatXX() total et exact
|
||||
|
||||
E+R
|
||||
toFloatXX() exact, peut fault Inexact
|
||||
roundToFloatXX() total
|
||||
|
||||
E+FR+SR
|
||||
toFloatXX() exact, peut fault Inexact/OutOfRange
|
||||
roundToFloatXX() peut fault OutOfRange
|
||||
saturatingRoundToFloatXX() total
|
||||
```
|
||||
|
||||
| Source \ Destination | float16 | float32 | float64 | float128 |
|
||||
|---|---|---|---|---|
|
||||
| int8 | T | T | T | T |
|
||||
| int16 | E+R | T | T | T |
|
||||
| int32 | E+TR+SR | E+R | T | T |
|
||||
| int64 | E+TR+SR | E+R | E+R | T |
|
||||
| int128 | E+TR+SR | E+R | E+R | E+R |
|
||||
| int256 | E+TR+SR | E+TR+SR | E+R | E+R |
|
||||
| int32 | E+FR+SR | E+R | T | T |
|
||||
| int64 | E+FR+SR | E+R | E+R | T |
|
||||
| int128 | E+FR+SR | E+R | E+R | E+R |
|
||||
| int256 | E+FR+SR | E+FR+SR | E+R | E+R |
|
||||
| uint8 | T | T | T | T |
|
||||
| uint16 | E+TR+SR | T | T | T |
|
||||
| uint32 | E+TR+SR | E+R | T | T |
|
||||
| uint64 | E+TR+SR | E+R | E+R | T |
|
||||
| uint128 | E+TR+SR | E+TR+SR | E+R | E+R |
|
||||
| uint256 | E+TR+SR | E+TR+SR | E+R | E+R |
|
||||
| uint16 | E+FR+SR | T | T | T |
|
||||
| uint32 | E+FR+SR | E+R | T | T |
|
||||
| uint64 | E+FR+SR | E+R | E+R | T |
|
||||
| uint128 | E+FR+SR | E+FR+SR | E+R | E+R |
|
||||
| uint256 | E+FR+SR | E+FR+SR | E+R | E+R |
|
||||
|
||||
Contrats :
|
||||
Exemple :
|
||||
|
||||
- `toFloatXX()` existe seulement si **toute** valeur source est exactement représentable ;
|
||||
- `tryToFloatXX()` exige une représentation exacte de la valeur courante ;
|
||||
- `roundToFloatXX()` existe seulement lorsque toute valeur source reste dans le domaine fini destination, mais qu'une perte de précision peut être nécessaire ;
|
||||
- `tryRoundToFloatXX()` accepte l'arrondi canonique mais retourne `Err` si la magnitude finie dépasse le domaine destination ;
|
||||
- `saturatingRoundToFloatXX()` est réservé aux paires pour lesquelles un débordement de domaine est possible : une valeur finie trop grande est bornée au plus grand fini de même signe, puis la précision destination s'applique selon l'arrondi canonique ;
|
||||
- il n'existe pas de `wrapToFloatXX()`.
|
||||
|
||||
Exemple distinct :
|
||||
|
||||
```saselang
|
||||
```text
|
||||
int64 value = ...;
|
||||
|
||||
Result<float64, NumericConversionError> exact = value::tryToFloat64();
|
||||
float64 exact = value::toFloat64();
|
||||
float64 approximated = value::roundToFloat64();
|
||||
```
|
||||
|
||||
`tryToFloat64()` et `roundToFloat64()` ne sont pas des alias : le premier refuse toute perte de précision, le second l'accepte explicitement.
|
||||
La première opération exige l'exactitude et peut produire `NumericConversionFault::Inexact`; la seconde accepte explicitement la perte de précision.
|
||||
|
||||
## A.7. Flottant -> flottant
|
||||
## A.8. Flottant -> flottant
|
||||
|
||||
Légende :
|
||||
|
||||
- `T` = `toFloatXX()` uniquement ;
|
||||
- `E+TR+SR` = `tryToFloatXX()` + `tryRoundToFloatXX()` + `saturatingRoundToFloatXX()`.
|
||||
```text
|
||||
T
|
||||
toFloatXX() total et exact
|
||||
|
||||
E+FR+SR
|
||||
toFloatXX() exact, peut fault
|
||||
roundToFloatXX() accepte l'arrondi, peut fault OutOfRange fini
|
||||
saturatingRoundToFloatXX() total
|
||||
```
|
||||
|
||||
| Source \ Destination | float16 | float32 | float64 | float128 |
|
||||
|---|---|---|---|---|
|
||||
| float16 | — | T | T | T |
|
||||
| float32 | E+TR+SR | — | T | T |
|
||||
| float64 | E+TR+SR | E+TR+SR | — | T |
|
||||
| float128 | E+TR+SR | E+TR+SR | E+TR+SR | — |
|
||||
| float32 | E+FR+SR | — | T | T |
|
||||
| float64 | E+FR+SR | E+FR+SR | — | T |
|
||||
| float128 | E+FR+SR | E+FR+SR | E+FR+SR | — |
|
||||
|
||||
Règles :
|
||||
|
||||
- l'élargissement de format est exact au niveau de la valeur IEEE et utilise uniquement `toFloatXX()` ;
|
||||
- la réduction de format propose `tryToFloatXX()` pour exiger l'exactitude, `tryRoundToFloatXX()` pour accepter la perte de précision mais pas le débordement fini, et `saturatingRoundToFloatXX()` pour obtenir une opération totale sur le domaine flottant ;
|
||||
- `NaN`, `+Infinity`, `-Infinity`, `+0` et `-0` restent des catégories IEEE valides dans la destination ;
|
||||
- pour `NaN`, seule la propriété sémantique `isNaN(destination) == true` est garantie ; payload, signe et quiet/signaling bit ne sont pas garantis par une conversion de valeur ;
|
||||
- `tryToFloatXX()` accepte `NaN` et les infinities lorsque la destination est un type flottant Saselang, car ces catégories y sont représentables ;
|
||||
- `saturatingRoundToFloatXX()` ne transforme pas une infinité en valeur finie puisque l'infinité est elle-même représentable dans le format destination ; la saturation explicite concerne les valeurs **finies** hors du domaine fini destination ;
|
||||
- la conservation exacte d'une représentation binaire relève d'un contrat binaire distinct et de `bitcast` lorsque ses propres contraintes sont compatibles.
|
||||
- l'élargissement de format utilise `toFloatXX()` total ;
|
||||
- la réduction exacte utilise `toFloatXX()` avec fault si nécessaire ;
|
||||
- `roundToFloatXX()` accepte la perte de précision mais pas un débordement fini ;
|
||||
- `saturatingRoundToFloatXX()` sature seulement les valeurs finies hors domaine fini ;
|
||||
- `NaN`, `+Infinity`, `-Infinity`, `+0` et `-0` restent des catégories valides ;
|
||||
- pour `NaN`, seule la propriété sémantique `isNaN(destination) == true` est garantie.
|
||||
|
||||
## A.8. Flottant -> entier : composition des politiques
|
||||
|
||||
Il n'existe jamais de simple `toIntXX()` ou `toUintXX()` depuis un flottant.
|
||||
## A.9. Flottant -> entier : composition des politiques
|
||||
|
||||
La conversion stricte canonique est :
|
||||
|
||||
```text
|
||||
tryToIntXX()
|
||||
tryToUintXX()
|
||||
toIntXX()
|
||||
toUintXX()
|
||||
```
|
||||
|
||||
Elle réussit uniquement si la valeur flottante est finie, mathématiquement entière, dans le domaine de la destination et exactement représentable comme entier destination. Sinon elle retourne `Err(NumericConversionError(...))`.
|
||||
avec :
|
||||
|
||||
### A.8.1. Politiques mathématiques séparées
|
||||
```text
|
||||
faults NumericConversionFault
|
||||
```
|
||||
|
||||
Les opérations Core :
|
||||
lorsque la valeur peut être non finie, non entière ou hors plage.
|
||||
|
||||
### A.9.1. Politiques mathématiques séparées
|
||||
|
||||
```text
|
||||
floor()
|
||||
@@ -211,67 +235,56 @@ round()
|
||||
truncate()
|
||||
```
|
||||
|
||||
restent des opérations sur le flottant et définissent chacune une politique mathématique unique.
|
||||
restent des opérations sur le flottant. Elles se composent ensuite avec la conversion :
|
||||
|
||||
Elles se composent ensuite avec les conversions :
|
||||
|
||||
```saselang
|
||||
value::floor()::tryToInt32()
|
||||
value::ceil()::tryToInt32()
|
||||
value::round()::tryToInt32()
|
||||
value::truncate()::tryToInt32()
|
||||
```text
|
||||
value::floor()::toInt32()
|
||||
value::ceil()::toInt32()
|
||||
value::round()::toInt32()
|
||||
value::truncate()::toInt32()
|
||||
```
|
||||
|
||||
Cette composition remplace les alias redondants `tryFloorTo...`, `tryCeilTo...`, `tryRoundTo...` et `tryTruncateTo...`.
|
||||
Aucun alias combiné n'est ajouté lorsqu'il serait strictement équivalent.
|
||||
|
||||
`round()` utilise la règle canonique **nearest, ties to even**.
|
||||
|
||||
### A.8.2. Dépassement de domaine
|
||||
|
||||
Les politiques de dépassement restent séparées de la politique mathématique.
|
||||
### A.9.2. Dépassement de domaine
|
||||
|
||||
Pour chaque destination entière, le Core peut exposer :
|
||||
|
||||
```text
|
||||
tryToTarget()
|
||||
trySaturateToTarget()
|
||||
tryWrapToTarget()
|
||||
toTarget()
|
||||
saturateToTarget()
|
||||
wrapToTarget()
|
||||
```
|
||||
|
||||
avec les contrats suivants :
|
||||
|
||||
| Opération | Préconditions non liées à la plage | Politique de plage |
|
||||
| Opération | Préconditions hors plage | Politique de plage |
|
||||
|---|---|---|
|
||||
| `tryToTarget()` | valeur finie et mathématiquement entière | `Err` si hors plage |
|
||||
| `trySaturateToTarget()` | valeur finie et mathématiquement entière | borne à `Target::Min` / `Target::Max` |
|
||||
| `tryWrapToTarget()` | valeur finie et mathématiquement entière | modulo `2^N` selon le type entier destination |
|
||||
| `toTarget()` | valeur finie et mathématiquement entière | `OutOfRange` si hors plage |
|
||||
| `saturateToTarget()` | valeur finie et mathématiquement entière | borne à `Target::Min` / `Target::Max` |
|
||||
| `wrapToTarget()` | valeur finie et mathématiquement entière | modulo `2^N` |
|
||||
|
||||
Les politiques se composent :
|
||||
`NotFinite` et `NotIntegral` restent possibles pour les trois familles lorsqu'elles s'appliquent.
|
||||
|
||||
```saselang
|
||||
value::floor()::trySaturateToInt32()
|
||||
value::round()::trySaturateToUint16()
|
||||
Exemples :
|
||||
|
||||
value::truncate()::tryWrapToInt8()
|
||||
value::ceil()::tryWrapToUint64()
|
||||
```text
|
||||
value::floor()::saturateToInt32()
|
||||
value::round()::saturateToUint16()
|
||||
value::truncate()::wrapToInt8()
|
||||
value::ceil()::wrapToUint64()
|
||||
```
|
||||
|
||||
Il n'existe pas de variantes combinées telles que `trySaturatingFloorToInt32()` ou `tryWrappingRoundToInt32()` lorsque la composition ci-dessus possède exactement la même sémantique.
|
||||
|
||||
### A.8.3. Matrice flottant -> entier après élimination des doublons
|
||||
|
||||
Pour chaque paire, la matrice conserve uniquement les politiques dont le résultat peut réellement différer sur une valeur source admissible.
|
||||
### A.9.3. Matrice flottant -> entier après élimination des doublons
|
||||
|
||||
Légende :
|
||||
|
||||
```text
|
||||
C
|
||||
tryToTarget() uniquement
|
||||
toTarget() uniquement
|
||||
|
||||
CSW
|
||||
tryToTarget()
|
||||
trySaturateToTarget()
|
||||
tryWrapToTarget()
|
||||
toTarget()
|
||||
saturateToTarget()
|
||||
wrapToTarget()
|
||||
```
|
||||
|
||||
| Source \ Destination | int8 | int16 | int32 | int64 | int128 | int256 | uint8 | uint16 | uint32 | uint64 | uint128 | uint256 |
|
||||
@@ -281,75 +294,37 @@ CSW
|
||||
| float64 | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW |
|
||||
| float128 | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW | CSW |
|
||||
|
||||
Justification :
|
||||
|
||||
- toutes les valeurs finies et mathématiquement entières de `float16` tiennent dans `int32` et les entiers signés plus larges ; saturation et wrapping n'apportent donc rien pour ces paires ;
|
||||
- toutes les valeurs finies et mathématiquement entières de `float32` tiennent dans `int256`, mais pas dans `int128` ou plus petit ;
|
||||
- pour toute destination non signée, les valeurs négatives rendent checked, saturation et wrapping distincts, même lorsque toute magnitude positive finie tient dans la destination ;
|
||||
- `float64` et `float128` disposent de valeurs finies dépassant le domaine de tous les entiers Saselang V1.
|
||||
|
||||
Cas particuliers :
|
||||
|
||||
- `+0` et `-0` donnent l'entier zéro ;
|
||||
- `NaN`, `+Infinity` et `-Infinity` échouent dans ces familles car ils ne satisfont pas la précondition de valeur finie et mathématiquement entière ;
|
||||
- pour une destination non signée, la saturation d'une valeur négative entière donne `0` ;
|
||||
- pour une destination signée, la saturation utilise `Target::Min` / `Target::Max` ;
|
||||
- le wrapping est appliqué au résultat entier mathématique fini selon modulo `2^N`.
|
||||
- `+0` et `-0` donnent zéro ;
|
||||
- `NaN` et les infinities produisent `NotFinite` ;
|
||||
- une valeur fractionnaire produit `NotIntegral` avant la politique de plage ;
|
||||
- vers un non signé, la saturation d'une valeur négative entière donne `0` ;
|
||||
- le wrapping s'applique à l'entier mathématique fini modulo `2^N`.
|
||||
|
||||
## A.9. `bitcast` reste hors de cette matrice
|
||||
## A.10. `bitcast` reste hors de cette matrice
|
||||
|
||||
`bitcast<T>(value)` n'est pas une conversion numérique. Il conserve les bits et change leur interprétation sous les contraintes de taille et de validité déjà définies par le langage.
|
||||
`bitcast<T>(value)` conserve les bits et change leur interprétation sous ses propres contraintes. Il ne constitue jamais une alternative implicite à `to...`, `round...`, `saturate...` ou `wrap...`.
|
||||
|
||||
Il ne constitue jamais une alternative implicite à `to...`, `try...`, `round...`, `saturate...` ou `wrap...`.
|
||||
|
||||
## A.10. Typage contextuel des littéraux
|
||||
## A.11. Typage contextuel des littéraux
|
||||
|
||||
Le typage contextuel d'un littéral reste distinct de toute conversion de valeur déjà typée.
|
||||
|
||||
```saselang
|
||||
int32 a = 42; // contextualisation du littéral
|
||||
```text
|
||||
int32 a = 42;
|
||||
|
||||
int8 small = ...;
|
||||
int32 b = small; // ERROR : pas de conversion implicite
|
||||
int32 c = small::toInt32(); // OK
|
||||
int32 b = small; // ERROR
|
||||
int32 c = small::toInt32(); // OK
|
||||
```
|
||||
|
||||
## A.11. Core, targets et capacités
|
||||
|
||||
Les membres de conversion appartiennent au Core des primitives. Le compilateur doit pouvoir reconnaître leur contrat via les métadonnées/Core intrinsics nécessaires sans transformer chaque membre en syntaxe spéciale.
|
||||
|
||||
Pour les conversions fondamentales de cette matrice :
|
||||
|
||||
> si les types source et destination sont supportés par le target, les opérations non redondantes définies par la matrice sont Core-required.
|
||||
|
||||
L'absence d'une instruction matérielle native ne rend pas l'opération optionnelle lorsqu'une émulation logicielle conforme est raisonnablement possible.
|
||||
|
||||
Un target réduit peut ne pas exposer un type fondamental donné. Dans ce cas, l'indisponibilité doit porter sur le type/capacité fondamentale, pas sur une sélection arbitraire de ses conversions.
|
||||
|
||||
La nomenclature générale des capabilities et leurs niveaux sont définis au chapitre 40.
|
||||
|
||||
## A.12. Hiérarchie documentaire cible
|
||||
|
||||
La documentation Saselang est destinée à être organisée par niveaux :
|
||||
## A.12. `NumericConversionFault`
|
||||
|
||||
```text
|
||||
Language / Compiler Specification
|
||||
ce que le compilateur doit accepter, refuser et produire
|
||||
|
||||
Saselang + Core Specification
|
||||
langage + environnement Core normatif
|
||||
|
||||
Saselang Platform Documentation
|
||||
langage + Core + SDKs + extensions de plateforme
|
||||
NumericConversionFault extends Fault
|
||||
```
|
||||
|
||||
Depuis `0.2.12`, la Bible est distribuée sous forme d'une archive multifichier structurée avec sommaire, chapitres séparés, exemples/DO-DON'T par chapitre et annexes référencées.
|
||||
|
||||
## A.13. `NumericConversionError`
|
||||
|
||||
`NumericConversionError` est le nom de travail du `ResultError` Core des conversions récupérables.
|
||||
|
||||
Les codes sémantiques V1 sont :
|
||||
Codes sémantiques V1 :
|
||||
|
||||
```text
|
||||
NotFinite
|
||||
@@ -358,19 +333,20 @@ OutOfRange
|
||||
Inexact
|
||||
```
|
||||
|
||||
L'erreur reste minimale et ne transporte pas automatiquement la valeur source, les types source/destination, le backend, un timestamp ou un mode d'arrondi.
|
||||
Le fault reste minimal et ne transporte pas automatiquement la valeur source, les types source/destination, le backend, un timestamp ou un mode d'arrondi.
|
||||
|
||||
## A.14. État de l'annexe
|
||||
## A.13. État de l'annexe
|
||||
|
||||
Les principes sémantiques de la matrice sont désormais largement figés :
|
||||
Principes largement figés :
|
||||
|
||||
```text
|
||||
non-redondance par paire
|
||||
composition plutôt qu'alias combinés
|
||||
Fault direct à la place des anciens try... purement mécaniques
|
||||
règles float -> integer
|
||||
règles NaN / infinities / signed zero
|
||||
NumericConversionError
|
||||
disponibilité Core pour les types supportés
|
||||
NumericConversionFault
|
||||
Core-required pour les types supportés
|
||||
émulation logicielle lorsque raisonnable
|
||||
```
|
||||
|
||||
@@ -378,5 +354,5 @@ Restent principalement à auditer lors de l'implémentation Core :
|
||||
|
||||
1. le listing mécanique exhaustif des membres concrets exposés par chaque primitive ;
|
||||
2. les noms définitifs des constantes/membres Core associés ;
|
||||
3. la représentation interne exacte des codes `NumericConversionError` ;
|
||||
3. la représentation interne exacte des codes `NumericConversionFault` ;
|
||||
4. les tests de conformité couvrant toutes les cellules de la matrice.
|
||||
|
||||
Reference in New Issue
Block a user