Skip to content

Instantly share code, notes, and snippets.

@ArtemGr
Last active July 9, 2023 19:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ArtemGr/4149756d2c9058f9d073f4a39a4ece9c to your computer and use it in GitHub Desktop.
Save ArtemGr/4149756d2c9058f9d073f4a39a4ece9c to your computer and use it in GitHub Desktop.
serde f16 73871891
extern crate half; // 2.3.1
extern crate serde; // 1.0.164
extern crate serde_json; // 1.0.99
use half::f16;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
fn f16ser<S>(fv: &f16, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
se.serialize_f64(fv.to_f64())
}
fn f16ser3<S>(fv: &f16, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
se.serialize_f64((fv.to_f64() * 1000.).round() / 1000.)
}
/* depends on `half` feature "num-traits" for `round` to work
fn _f16des3<'de, D>(des: D) -> Result<f16, D::Error>
where
D: Deserializer<'de>,
{
use num_traits::float::Float;
f64::deserialize(des).and_then(|fv| {
const R3: f16 = f16::from_f32_const(1000.);
Ok((f16::from_f64(fv) * R3).round() / R3)
})
}*/
fn f16des3<'de, D>(des: D) -> Result<f16, D::Error>
where
D: Deserializer<'de>,
{
f64::deserialize(des).and_then(|fv| Ok(f16::from_f64(fv)))
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[repr(packed)]
struct Foo {
#[serde(serialize_with = "f16ser", deserialize_with = "f16des3")]
foo: f16,
#[serde(serialize_with = "f16ser3", deserialize_with = "f16des3")]
bar: f16,
}
fn main() {
let foo = Foo {
foo: f16::from_f32(1.23), // Demonstrates round-off error.
bar: f16::from_f32(1.23), // Roundoff error hidden by rounding.
};
let foo_s = serde_json::to_string(&foo).unwrap();
println!("{}", foo_s); // {"foo":1.23046875,"bar":1.23}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment