Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_jdat/tests/float_text.rs

1.8 KiB, 1 run

created by r1870400018:59726, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! A decimal read from text becomes the nearest float, as every JSON reader makes it.
2//!
3//! Dated 2026-09-23: `get_float64` turned a decoded decimal into a float by scaling its digits
4//! by a power of ten in floating point, which rounds twice, so `0.3` came back as
5//! `0.30000000000000004`. Found rebuilding a Natural Earth world from GeoJSON, where a
6//! coordinate one unit in the last place off rounds to a different metre.
7
8use oxedyne_fe2o3_jdat::{
9 prelude::*,
10 string::dec::DecoderConfig,
11 usr::{
12 UsrKind,
13 UsrKindCode,
14 UsrKindId,
15 },
16};
17
18use oxedyne_fe2o3_core::prelude::*;
19
20use std::collections::BTreeMap;
21
22#[test]
23fn test_a_json_decimal_reads_as_the_nearest_float_00() -> Outcome<()> {
24 let text = "[0.3, 115.8571, -31.9535, 0.1, 1.7976931348623157e308, 5e-324, \
25 -179.99999999999997, 2.5e3, 12345678901234567890.123]";
26 let cfg = DecoderConfig::<BTreeMap<UsrKindCode, UsrKind>, BTreeMap<String, UsrKindId>>::json(None);
27 let dat = res!(Dat::decode_string_with_config(text, &cfg));
28 let list = match dat {
29 Dat::List(v) => v,
30 other => return Err(err!("Expected a list, got {:?}.", other.kind(); Mismatch)),
31 };
32 // The oracle is the standard library's parser, which rounds to nearest as IEEE 754 and
33 // every conforming JSON reader do.
34 let want: Vec<f64> = res!(text.trim_matches(|c| c == '[' || c == ']')
35 .split(',')
36 .map(|s| s.trim().parse::<f64>())
37 .collect::<Result<Vec<f64>, _>>());
38 req!(list.len(), want.len());
39 for (d, w) in list.iter().zip(want.iter()) {
40 let got = match d.get_float64() {
41 Some(f) => f.0,
42 None => return Err(err!("{:?} did not read as a float.", d; Mismatch)),
43 };
44 req!(got.to_bits(), w.to_bits(), "{:?} read as {:e}, not {:e}.", d, got, w);
45 }
46 Ok(())
47}