106 / Entrada, salida y datos

JSON: números exactos

json_stringify sobre un nodo reemite el número EXACTO tal como llegó en el texto de origen, ceros de más incluidos. json_as_float en cambio pasa por un double y después float_to_string devuelve la forma mínima que vuelve a ese mismo double — así que 19.90 puede volver como 19.9. Para mostrar un precio con un ancho fijo de decimales está float_to_fixed.

106-json-exact-numbers.nxFuente →
// JSON: json_stringify sobre un nodo reemite el número EXACTO tal como vino
// (con sus ceros de más incluidos), a diferencia de json_as_float +
// float_to_string, que pasa por un double y devuelve la forma MÍNIMA que
// vuelve a ese mismo double. float_to_fixed sirve para volver a un ancho
// fijo de decimales (precios).

import "std/json"
import "std/math_ext"

fn main() -> int {
    let doc: String = "{\"precio\": 19.90, \"embedding\": [0.013426971, 0.1]}"
    let parsed: Array = json_parse(doc)

    // El documento completo reemitido: cada número, tal como vino.
    print(json_stringify(parsed))

    let precio_node: Array = json_get(parsed, "precio")
    print(json_stringify(precio_node))          // texto exacto: conserva el cero

    let embedding_node: Array = json_get(parsed, "embedding")
    print(json_stringify(embedding_node))       // literal exacto, sirve para pgvector

    // json_as_float + float_to_string: pasa por un double.
    let precio: float = json_as_float(precio_node)
    print(float_to_string(precio))              // perdió el cero de más

    // Ancho fijo de decimales para mostrar el precio de nuevo:
    print(float_to_fixed(precio, 2))

    return 0
}
Salidastdout
{"precio":19.90,"embedding":[0.013426971,0.1]}
19.90
[0.013426971,0.1]
19.9
19.90

Cómo funciona

El documento completo reemitido conserva cada número tal como estaba escrito: 19.90 sigue siendo 19.90, no 19.9. Lo mismo pasa al reemitir un nodo suelto con json_stringify(precio_node): es texto exacto, no una vuelta por punto flotante.

embedding_node muestra por qué esto importa más allá de la estética: un array de flotantes de alta precisión —el caso típico de un embedding para pgvector— necesita conservar cada dígito para no perder precisión en la ida y vuelta.

json_as_float(precio_node) sí pasa por un double, y float_to_string imprime la representación mínima que redondea de vuelta al mismo valor: el cero de más se pierde. float_to_fixed(precio, 2) lo recupera para mostrar, forzando dos decimales sin depender de qué trajo el JSON original.