Unusual floats. Still thinking about this

This commit is contained in:
Tony Garnock-Jones 2022-11-04 22:17:08 +01:00
parent 6faa910aef
commit d8079f0dd4
2 changed files with 101 additions and 4 deletions

View File

@ -76,3 +76,89 @@ mod formatting_tests {
"]"));
}
}
#[cfg(test)]
mod unusual_float_tests {
use std::io;
use crate::*;
fn d32(v: f32) {
println!("{}{}{}{}{:?}: preserves {:?}",
if v.is_nan() { "nan " } else { "" },
if v.is_infinite() { "inf " } else { "" },
if v.is_subnormal() { "sub " } else { "" },
if v.is_sign_positive() { "+ve " } else { "-ve " },
v,
iovalue(v));
}
fn d64(v: f64) {
println!("{}{}{}{}{:?}: preserves {:?}",
if v.is_nan() { "nan " } else { "" },
if v.is_infinite() { "inf " } else { "" },
if v.is_subnormal() { "sub " } else { "" },
if v.is_sign_positive() { "+ve " } else { "-ve " },
v,
iovalue(v));
}
#[test] fn subnormal32() -> io::Result<()> {
d32(f32::from_bits(0x00000100));
d32(f32::from_bits(0x80000100));
Ok(())
}
#[test] fn normal32() -> io::Result<()> {
d32(f32::from_bits(0x01000000));
d32(f32::from_bits(0x81000000));
Ok(())
}
#[test] fn nan32() -> io::Result<()> {
d32(f32::from_bits(0x7fc00000));
d32(f32::from_bits(0x7fc5a5a5));
d32(f32::from_bits(0x7f800001));
d32(f32::from_bits(0x7f85a5a5));
d32(f32::from_bits(0xffc00000));
d32(f32::from_bits(0xffc5a5a5));
d32(f32::from_bits(0xff800001));
d32(f32::from_bits(0xff85a5a5));
Ok(())
}
#[test] fn inf32() -> io::Result<()> {
d32(f32::from_bits(0x7f800000));
d32(f32::from_bits(0xff800000));
Ok(())
}
#[test] fn subnormal64() -> io::Result<()> {
d64(f64::from_bits(0x0000000000000100));
d64(f64::from_bits(0x8000000000000100));
Ok(())
}
#[test] fn normal64() -> io::Result<()> {
d64(f64::from_bits(0x0100000000000000));
d64(f64::from_bits(0x8100000000000000));
Ok(())
}
#[test] fn nan64() -> io::Result<()> {
d64(f64::from_bits(0x7ff8000000000000));
d64(f64::from_bits(0x7ff85a5a5a5a5a5a));
d64(f64::from_bits(0x7ff0000000000001));
d64(f64::from_bits(0x7ff05a5a5a5a5a5a));
d64(f64::from_bits(0xfff8000000000000));
d64(f64::from_bits(0xfff85a5a5a5a5a5a));
d64(f64::from_bits(0xfff0000000000001));
d64(f64::from_bits(0xfff05a5a5a5a5a5a));
Ok(())
}
#[test] fn inf64() -> io::Result<()> {
d64(f64::from_bits(0x7ff0000000000000));
d64(f64::from_bits(0xfff0000000000000));
Ok(())
}
}

View File

@ -4,6 +4,7 @@ use crate::IOValue;
use crate::IOValueDomainCodec;
use crate::Value;
use crate::Writer;
use crate::hex::HexFormatter;
use num_bigint::BigInt;
@ -205,13 +206,23 @@ impl<W: io::Write> Writer for TextWriter<W> {
}
fn write_f32(&mut self, v: f32) -> io::Result<()> {
dtoa::write(&mut self.w, v)?;
write!(self.w, "f")
if f32::is_normal(v) || f32::is_subnormal(v) {
dtoa::write(&mut self.w, v)?;
write!(self.w, "f")
} else {
let bs = v.to_be_bytes();
write!(self.w, "#p#x\"{}\"", HexFormatter::Packed.encode(&bs))
}
}
fn write_f64(&mut self, v: f64) -> io::Result<()> {
dtoa::write(&mut self.w, v)?;
Ok(())
if f64::is_normal(v) || f64::is_subnormal(v) {
dtoa::write(&mut self.w, v)?;
Ok(())
} else {
let bs = v.to_be_bytes();
write!(self.w, "#p#x\"{}\"", HexFormatter::Packed.encode(&bs))
}
}
fn write_i128(&mut self, v: i128) -> io::Result<()> {