Números de punto flotante (XFL)
Contexto
Sección titulada «Contexto»Los números de punto flotante se utilizan ampliamente en informática para realizar cálculos de precisión finita pero escala arbitraria.
La mayoría de las CPUs modernas son capaces de realizar operaciones rápidas de punto flotante utilizando el estándar IEEE de punto flotante binario, sin embargo xahaud no utiliza este formato. En su lugar, Xahau utiliza un estándar decimal de punto flotante personalizado.
Este formato personalizado tiene tres propiedades básicas:
- El formato es inherentemente decimal, expresado como una
mantisadecimal multiplicada por10elevado a unexponente. - Todos los valores expresados tienen 16 cifras significativas (decimales).
- El rango de exponentes es de
-96a+80.
Cuando se serializa, la mantisa ocupa 54 bits y el exponente 8 bits, con un bit adicional de signo que lleva el tamaño total a 63 bits.
¿Qué es XFL?
Sección titulada «¿Qué es XFL?»XLS-17d es una propuesta de estándar XRPL que define una forma eficiente de empaquetar y almacenar números de punto flotante en xrpld (como se describió anteriormente).
Los XFL almacenan los bits del número de punto flotante dentro de un número contenedor. Este siempre es un int64_t. Los números contenedores negativos representan XFL inválidos (por ejemplo, como resultado de una división por cero).
Algunos ejemplos de XFL:
| Valor de punto flotante | Número contenedor | Representación |
|---|---|---|
| -1 | 1478180677777522688 | -1000000000000000 * 10^(-15) |
| 0 | 0 | 0 (cero canónico) |
| 1 | 6089866696204910592 | +1000000000000000 * 10^(-15) |
| PI | 6092008288858500385 | +3141592653589793 * 10^(-15) |
| -PI | 1480322270431112481 | -3141592653589793 * 10^(-15) |
Este formato es muy conveniente para Hooks, ya que solo pueden intercambiar valores enteros con xrpld. Al encapsular el número de punto flotante dentro de un entero de forma bien definida, es posible realizar cálculos complejos de punto flotante desde un Hook. Esto resulta útil, por ejemplo, para calcular tipos de cambio.
Cero canónico
Sección titulada «Cero canónico»Los sistemas de punto flotante suelen tener múltiples formas de representar el cero, lo que puede causar problemas al comprobarlo. Por ejemplo, 0 x 10 ^ 1 es cero y 0 x 10 ^ 2 también es cero. Por esta razón, el estándar y la API de Hooks imponen un cero canónico. Este corresponde al número contenedor cero (0).
API de Float en Hooks
Sección titulada «API de Float en Hooks»Una vez que tienes un XFL, puedes usar la API de Float para realizar distintos cálculos. Cada función recibe uno o más números contenedores XFL y devuelve otro número contenedor XFL. Los valores negativos siempre representan un error de cálculo (como división por cero). No existen números contenedores negativos válidos.
| Hook API | Qué hace |
|---|---|
| float_set | Crear un float a partir de un exponente y una mantisa |
| float_multiply | Multiplicar dos números XFL |
| float_mulratio | Multiplicar un XFL por un numerador y denominador no-XFL |
| float_negate | Negar un número de punto flotante XFL |
| float_compare | Comparar dos números XFL |
| float_sum | Sumar dos números XFL |
| float_sto | Convertir un XFL en un objeto serializado |
| float_sto_set | Leer una cantidad serializada en un XFL |
| float_invert | Calcular el inverso de un XFL |
| float_divide | Dividir un XFL entre otro XFL |
| float_one | Devolver el número 1 como XFL |
| float_exponent | Obtener el exponente de un XFL |
| float_mantissa | Obtener la mantisa de un XFL |
| float_sign | Obtener el signo de un XFL |
| float_exponent_set | Establecer el exponente de un XFL |
| float_mantissa_set | Establecer la mantisa de un XFL |
| float_sign_set | Establecer el signo de un XFL |
| float_int | Convertir un XFL a entero (redondeo hacia abajo) |
| float_root | Calcular la raíz n-ésima de un XFL |
| float_log | Calcular el logaritmo decimal de un XFL |
Ejemplo
Sección titulada «Ejemplo»En el siguiente ejemplo se realiza una conversión de tipo de cambio seguida de una multiplicación de fracciones de alta precisión:
int64_t max_vault_pusd = float_multiply(vault_xrp, exchange_rate);
max_vault_pusd = float_mulratio(max_vault_pusd, 0, NEW_COLLATERALIZATION_NUMERATOR, NEW_COLLATERALIZATION_DENOMINATOR);