This commit is contained in:
2026-09-12 18:12:13 +02:00
parent 18306bdc8c
commit 57ae671f88
27 changed files with 2060 additions and 623 deletions

View File

@@ -87,31 +87,168 @@ Une forme n'existe que si elle apporte une sémantique observable différente d'
Ainsi, lorsqu'un `toTarget()` exact et total existe, les variantes `tryToTarget()`, `saturateToTarget()` ou `wrapToTarget()` qui produiraient exactement le même résultat pour tout le domaine source sont absentes.
Règle de composition : deux opérations Core ne sont fusionnées dans un même nom que si leur séparation en opérations successives modifierait la sémantique, perdrait de l'information ou empêcherait d'exprimer le même contrat.
Lorsqu'une composition existante est strictement équivalente, aucun alias combiné n'est ajouté au Core.
## 24.6 `float -> integer` — V1 REQUIS — DIRECTION FIGÉE
Un flottant ne possède jamais un simple `toIntXX()` ou `toUintXX()`.
La politique de passage du réel à l'entier doit être explicite, par exemple :
La conversion exacte stricte utilise :
```text
tryExactToInt32()
tryFloorToInt32()
tryCeilToInt32()
tryRoundToInt32()
tryTruncateToInt32()
tryToIntXX()
tryToUintXX()
```
Les variantes saturantes ou wrapping, lorsqu'elles sont retenues, doivent également annoncer explicitement la politique mathématique appliquée.
Elle réussit uniquement si la valeur source est finie, mathématiquement entière et représentable exactement dans le type destination. Sinon elle retourne `Result::Err(NumericConversionError(...))`.
Les politiques mathématiques de traitement de la partie fractionnaire restent des opérations Core séparées :
```text
floor()
ceil()
round()
truncate()
```
Elles se composent avec la conversion :
```text
value::floor()::tryToInt32()
value::ceil()::tryToInt32()
value::round()::tryToInt32()
value::truncate()::tryToInt32()
```
Saselang n'introduit donc pas les alias redondants `tryFloorToInt32()`, `tryCeilToInt32()`, `tryRoundToInt32()` ou `tryTruncateToInt32()` lorsque ces compositions possèdent exactement la même sémantique.
Les politiques de dépassement de domaine suivent la même règle :
```text
value::floor()::trySaturateToInt32()
value::round()::tryWrapToInt32()
```
`trySaturateToIntXX()` exige une valeur finie et mathématiquement entière, puis sature aux bornes du type destination. Les échecs qui ne relèvent pas de la plage, par exemple `NaN`, une infinité ou une valeur fractionnaire, restent des `NumericConversionError`.
`tryWrapToIntXX()` exige également une valeur finie et mathématiquement entière, puis applique le wrapping entier modulo `2^N` défini par Saselang.
Une méthode combinée reste admise lorsqu'une décomposition changerait le contrat ou perdrait l'information nécessaire. C'est notamment le cas de `saturatingRoundToFloat32()` pour certains narrowings flottants : un `roundToFloat32()` séparé pourrait échouer avant que la saturation ne puisse être appliquée.
Aucun comportement de conversion ne dépend d'un profil, d'un linter ou d'un backend.
## 24.7 `NumericConversionError` — V1 REQUIS — NOM DE TRAVAIL
## 24.7 `float -> float`, valeurs IEEE spéciales — V1 REQUIS — FIGÉ
Toute conversion de valeur flottante préserve les catégories sémantiques suivantes lorsque la destination est un type flottant Saselang :
```text
NaN -> NaN
+Infinity -> +Infinity
-Infinity -> -Infinity
+0 -> +0
-0 -> -0
```
Pour `NaN`, la conversion garantit uniquement que la destination reste `NaN`.
Elle ne garantit pas lors d'une conversion de valeur :
```text
payload NaN
quiet/signaling bit
signe du NaN
représentation binaire exacte
```
Ces propriétés relèvent d'un éventuel contrat binaire distinct ; `bitcast<T>` ne peut les préserver que lorsque ses propres contraintes, notamment de taille, sont satisfaites.
`tryToFloatXX()` traite `NaN` et les infinités comme des valeurs sémantiques représentables du type flottant destination. Le mot « exact » désigne ici l'exactitude de la valeur sémantique Saselang, pas l'identité bit-à-bit d'un payload NaN.
Pour une valeur finie :
```text
tryToFloatXX()
exige une représentation exacte
tryRoundToFloatXX()
accepte l'arrondi canonique
refuse une valeur finie hors domaine fini destination
saturatingRoundToFloatXX()
accepte l'arrondi canonique
sature une valeur finie hors domaine vers +/-Target::Max
```
Les infinités ne sont pas saturées puisqu'elles sont déjà des valeurs représentables du format flottant destination.
## 24.8 `NumericConversionError` — V1 REQUIS — NOM DE TRAVAIL / CODES FIGÉS
`NumericConversionError` est retenu comme nom de travail du `ResultError` Core utilisé par les conversions numériques récupérables.
Son nom définitif, ses codes et son état minimal pourront encore être ajustés lors de la finalisation du Core sans modifier les principes de conversion de ce chapitre.
Les catégories sémantiques V1 sont :
## 24.8 Matrice exhaustive — ANNEXE NORMATIVE EN COURS DE GEL
```text
NotFinite
NotIntegral
OutOfRange
Inexact
```
Sens :
```text
NotFinite
NaN ou +/-Infinity lorsqu'une valeur finie est requise
NotIntegral
float -> integer alors que la valeur n'est pas mathématiquement entière
OutOfRange
valeur mathématique hors du domaine de la destination
Inexact
valeur dans le domaine destination mais non représentable exactement
alors que l'opération exige l'exactitude
```
`NumericConversionError` reste volontairement généraliste et minimal. Il n'ajoute pas automatiquement :
```text
sourceType
targetType
sourceValue
timestamp
backend
roundingMode
```
au-delà de l'état commun fourni par `ResultError`.
Le nom concret et la représentation numérique interne des codes pourront encore être ajustés avant stabilisation publique, mais les catégories sémantiques ci-dessus font partie du contrat V1.
## 24.9 Réduction anti-doublon par paire — V1 REQUIS — FIGÉ
La matrice examine chaque paire `Source -> Target` et n'expose que les opérations dont le comportement peut réellement être distingué sur le domaine source.
Ainsi, pour une paire `float -> integer` dont toutes les valeurs finies mathématiquement entières sont déjà dans le domaine signé destination, `trySaturateToTarget()` et `tryWrapToTarget()` seraient des doublons de `tryToTarget()` et n'existent pas.
Pour une destination non signée, les valeurs négatives suffisent généralement à rendre les politiques checked, saturating et wrapping distinctes.
La matrice exhaustive en annexe est normative sur ce point.
## 24.10 Disponibilité Core et target — V1 REQUIS — FIGÉ EN PRINCIPE
Les conversions fondamentales de la matrice sont des capacités Core obligatoires dès lors que les types source et destination sont supportés par le target.
L'absence d'une instruction matérielle native ne justifie pas l'absence d'une conversion si une émulation logicielle conforme est raisonnablement possible.
Un target réduit peut ne pas supporter un type fondamental donné. Dans ce cas l'indisponibilité porte sur le type/capacité fondamentale, pas sur une sélection arbitraire de ses méthodes de conversion.
Voir également le chapitre 40.
## 24.11 Matrice exhaustive — ANNEXE NORMATIVE EN COURS DE GEL
L'inventaire source → destination des opérations de conversion est maintenu séparément afin d'éviter les oublis, doublons et incohérences.