1#![allow(
5 clippy::cast_lossless,
6 clippy::cast_sign_loss,
7 clippy::arithmetic_side_effects
8)]
9
10use crate::{
11 BytesRef, DecodeValue, EncodeValue, Error, FixedTag, Header, Length, Reader, Result, StringRef,
12 Tag, Writer,
13};
14
15use super::integer::uint::strip_leading_zeroes;
16
17impl<'a> DecodeValue<'a> for f64 {
18 type Error = Error;
19
20 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
21 let bytes = <&'a BytesRef>::decode_value(reader, header)?.as_slice();
22
23 if header.length() == Length::ZERO {
24 Ok(0.0)
25 } else if is_nth_bit_one::<7>(bytes) {
26 let sign: u64 = u64::from(is_nth_bit_one::<6>(bytes));
28
29 let base = mnth_bits_to_u8::<5, 4>(bytes);
31
32 if base != 0 {
33 return Err(reader.error(Tag::Real.value_error()));
35 }
36
37 let scaling_factor = mnth_bits_to_u8::<3, 2>(bytes);
39
40 let mantissa_start;
42 let exponent = match mnth_bits_to_u8::<1, 0>(bytes) {
43 0 => {
44 mantissa_start = 2;
45 let ebytes = (i16::from_be_bytes([0x0, bytes[1]])).to_be_bytes();
46 u64::from_be_bytes([0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ebytes[0], ebytes[1]])
47 }
48 1 => {
49 mantissa_start = 3;
50 let ebytes = (i16::from_be_bytes([bytes[1], bytes[2]])).to_be_bytes();
51 u64::from_be_bytes([0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ebytes[0], ebytes[1]])
52 }
53 _ => {
54 return Err(reader.error(Tag::Real.value_error()));
56 }
57 };
58 let mut n_bytes = [0x0; 8];
60 for (pos, byte) in bytes[mantissa_start..].iter().rev().enumerate() {
61 n_bytes[7 - pos] = *byte;
62 }
63 let n = u64::from_be_bytes(n_bytes);
64 let mantissa = n << scaling_factor;
66 Ok(encode_f64(sign, exponent, mantissa))
68 } else if is_nth_bit_one::<6>(bytes) {
69 match mnth_bits_to_u8::<1, 0>(bytes) {
71 0 => Ok(f64::INFINITY),
72 1 => Ok(f64::NEG_INFINITY),
73 2 => Ok(f64::NAN),
74 3 => Ok(-0.0_f64),
75 _ => Err(reader.error(Tag::Real.value_error())),
76 }
77 } else {
78 let astr = StringRef::from_bytes(&bytes[1..])?;
79 match astr.as_str().parse::<f64>() {
80 Ok(val) => Ok(val),
81 Err(_) => Err(reader.error(Tag::Real.value_error())),
83 }
84 }
85 }
86}
87
88impl EncodeValue for f64 {
89 fn value_len(&self) -> Result<Length> {
90 if self.is_sign_positive() && (*self) < f64::MIN_POSITIVE {
91 Ok(Length::ZERO)
93 } else if self.is_nan()
94 || self.is_infinite()
95 || (self.is_sign_negative() && -self < f64::MIN_POSITIVE)
96 {
97 Ok(Length::ONE)
99 } else {
100 let (_sign, exponent, mantissa) = decode_f64(*self);
102
103 let exponent_len = if exponent == 0 {
104 Length::ONE
107 } else {
108 let ebytes = exponent.to_be_bytes();
109 Length::try_from(strip_leading_zeroes(&ebytes).len())?
110 };
111
112 let mantissa_len = if mantissa == 0 {
113 Length::ONE
114 } else {
115 let mbytes = mantissa.to_be_bytes();
116 Length::try_from(strip_leading_zeroes(&mbytes).len())?
117 };
118
119 exponent_len + mantissa_len + Length::ONE
120 }
121 }
122
123 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
124 if self.is_nan()
128 || self.is_infinite()
129 || (self.is_sign_negative() && -self < f64::MIN_POSITIVE)
130 || (self.is_sign_positive() && (*self) < f64::MIN_POSITIVE)
131 {
132 if self.is_sign_positive() && (*self) < f64::MIN_POSITIVE {
133 return Ok(());
135 } else if self.is_nan() {
136 writer.write_byte(0b0100_0010)?;
138 } else if self.is_infinite() {
139 if self.is_sign_negative() {
140 writer.write_byte(0b0100_0001)?;
142 } else {
143 writer.write_byte(0b0100_0000)?;
145 }
146 } else {
147 writer.write_byte(0b0100_0011)?;
149 }
150 } else {
151 let mut first_byte = 0b1000_0000;
153
154 if self.is_sign_negative() {
155 first_byte |= 0b0100_0000;
157 }
158
159 let (_sign, exponent, mantissa) = decode_f64(*self);
166
167 let exponent_bytes = exponent.to_be_bytes();
169 let ebytes = strip_leading_zeroes(&exponent_bytes);
170
171 match ebytes.len() {
172 0 | 1 => {}
173 2 => first_byte |= 0b0000_0001,
174 3 => first_byte |= 0b0000_0010,
175 _ => {
176 return Err(Tag::Real.value_error().into());
178 }
179 }
180
181 writer.write_byte(first_byte)?;
182
183 writer.write(ebytes)?;
186
187 let mantissa_bytes = mantissa.to_be_bytes();
189 let mbytes = strip_leading_zeroes(&mantissa_bytes);
190 writer.write(mbytes)?;
191 }
192
193 Ok(())
194 }
195}
196
197impl FixedTag for f64 {
198 const TAG: Tag = Tag::Real;
199}
200
201pub(crate) fn is_nth_bit_one<const N: usize>(bytes: &[u8]) -> bool {
204 if N < 8 {
205 bytes.first().is_some_and(|byte| byte & (1 << N) != 0)
206 } else {
207 false
208 }
209}
210
211pub(crate) fn mnth_bits_to_u8<const M: usize, const N: usize>(bytes: &[u8]) -> u8 {
213 let bit_m = is_nth_bit_one::<M>(bytes);
214 let bit_n = is_nth_bit_one::<N>(bytes);
215 ((bit_m as u8) << 1) | bit_n as u8
216}
217
218#[allow(clippy::cast_possible_truncation)]
221pub(crate) fn decode_f64(f: f64) -> (u64, u64, u64) {
222 let bits = f.to_bits();
223 let sign = bits >> 63;
224 let exponent = (bits >> 52) & 0x7ff;
225 let exponent_bytes_no_bias = (exponent as i16 - 1023).to_be_bytes();
226 let exponent_no_bias = u64::from_be_bytes([
227 0x0,
228 0x0,
229 0x0,
230 0x0,
231 0x0,
232 0x0,
233 exponent_bytes_no_bias[0],
234 exponent_bytes_no_bias[1],
235 ]);
236 let mantissa = bits & 0xfffffffffffff;
237 (sign, exponent_no_bias, mantissa + 1)
238}
239
240pub(crate) fn encode_f64(sign: u64, exponent: u64, mantissa: u64) -> f64 {
242 let exponent_with_bias =
244 (i16::from_be_bytes([exponent.to_be_bytes()[6], exponent.to_be_bytes()[7]]) + 1023) as u64;
245 let bits = (sign << 63) | (exponent_with_bias << 52) | (mantissa - 1);
246 f64::from_bits(bits)
247}
248
249#[cfg(test)]
250#[allow(clippy::unwrap_used)]
251mod tests {
252 use crate::{Decode, Encode};
253
254 #[test]
255 fn decode_subnormal() {
256 assert!(f64::from_der(&[0x09, 0x01, 0b0100_0010]).unwrap().is_nan());
257 let plus_infty = f64::from_der(&[0x09, 0x01, 0b0100_0000]).unwrap();
258 assert!(plus_infty.is_infinite() && plus_infty.is_sign_positive());
259 let neg_infty = f64::from_der(&[0x09, 0x01, 0b0100_0001]).unwrap();
260 assert!(neg_infty.is_infinite() && neg_infty.is_sign_negative());
261 let neg_zero = f64::from_der(&[0x09, 0x01, 0b0100_0011]).unwrap();
262 assert!(neg_zero.is_sign_negative() && neg_zero.abs() < f64::EPSILON);
263 }
264
265 #[test]
266 fn encode_subnormal() {
267 let mut buffer = [0u8; 3];
269 assert_eq!(
270 &[0x09, 0x01, 0b0100_0010],
271 f64::NAN.encode_to_slice(&mut buffer).unwrap()
272 );
273 assert_eq!(
274 &[0x09, 0x01, 0b0100_0000],
275 f64::INFINITY.encode_to_slice(&mut buffer).unwrap()
276 );
277 assert_eq!(
278 &[0x09, 0x01, 0b0100_0001],
279 f64::NEG_INFINITY.encode_to_slice(&mut buffer).unwrap()
280 );
281 assert_eq!(
282 &[0x09, 0x01, 0b0100_0011],
283 (-0.0_f64).encode_to_slice(&mut buffer).unwrap()
284 );
285 }
286
287 #[test]
288 fn encdec_normal() {
289 {
291 let val = 0.0;
293 let expected = &[0x09, 0x0];
294 let mut buffer = [0u8; 2];
295 let encoded = val.encode_to_slice(&mut buffer).unwrap();
296 assert_eq!(
297 expected, encoded,
298 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
299 );
300 let decoded = f64::from_der(encoded).unwrap();
301 assert!(
302 (decoded - val).abs() < f64::EPSILON,
303 "wanted: {val}\tgot: {decoded}"
304 );
305 }
306
307 {
308 let val = 1.0;
310 let expected = &[0x09, 0x03, 0x80, 0x00, 0x01];
311 let mut buffer = [0u8; 5];
312 let encoded = val.encode_to_slice(&mut buffer).unwrap();
313 assert_eq!(
314 expected, encoded,
315 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
316 );
317 let decoded = f64::from_der(encoded).unwrap();
318 assert!(
319 (decoded - val).abs() < f64::EPSILON,
320 "wanted: {val}\tgot: {decoded}"
321 );
322 }
323
324 {
325 let val = -1.0;
327 let expected = &[0x09, 0x03, 0xc0, 0x00, 0x01];
328 let mut buffer = [0u8; 5];
329 let encoded = val.encode_to_slice(&mut buffer).unwrap();
330 assert_eq!(
331 expected, encoded,
332 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
333 );
334 let decoded = f64::from_der(encoded).unwrap();
335 assert!(
336 (decoded - val).abs() < f64::EPSILON,
337 "wanted: {val}\tgot: {decoded}"
338 );
339 }
340
341 {
342 let val = -1.0000000000000002;
344 let expected = &[0x09, 0x03, 0xc0, 0x00, 0x02];
345 let mut buffer = [0u8; 5];
346 let encoded = val.encode_to_slice(&mut buffer).unwrap();
347 assert_eq!(
348 expected, encoded,
349 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
350 );
351 let decoded = f64::from_der(encoded).unwrap();
352 assert!(
353 (decoded - val).abs() < f64::EPSILON,
354 "wanted: {val}\tgot: {decoded}"
355 );
356 }
357
358 {
359 let val = f64::MIN_POSITIVE;
362 let expected = &[0x09, 0x04, 0x81, 0xfc, 0x02, 0x01];
363 let mut buffer = [0u8; 7];
364 let encoded = val.encode_to_slice(&mut buffer).unwrap();
365 assert_eq!(
366 expected, encoded,
367 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
368 );
369 let decoded = f64::from_der(encoded).unwrap();
370 assert!(
371 (decoded - val).abs() < f64::EPSILON,
372 "wanted: {val}\tgot: {decoded}"
373 );
374 }
375
376 {
377 let val = 1.0000000000000016;
379 let expected = &[0x09, 0x03, 0x80, 0x00, 0x08];
380 let mut buffer = [0u8; 5];
381 let encoded = val.encode_to_slice(&mut buffer).unwrap();
382 assert_eq!(
383 expected, encoded,
384 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
385 );
386 let decoded = f64::from_der(encoded).unwrap();
387 assert!(
388 (decoded - val).abs() < f64::EPSILON,
389 "wanted: {val}\tgot: {decoded}"
390 );
391 }
392
393 {
394 let val = 31.0;
396 let expected = &[
397 0x9, 0x9, 0x80, 0x04, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
398 ];
399 let mut buffer = [0u8; 11];
400 let encoded = val.encode_to_slice(&mut buffer).unwrap();
401 assert_eq!(
402 expected, encoded,
403 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
404 );
405 let decoded = f64::from_der(encoded).unwrap();
406 assert!(
407 (decoded - val).abs() < f64::EPSILON,
408 "wanted: {val}\tgot: {decoded}"
409 );
410 }
411 }
412
413 #[test]
414 fn encdec_irrationals() {
415 {
416 let val = core::f64::consts::PI;
417 let expected = &[
418 0x09, 0x09, 0x80, 0x01, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x19,
419 ];
420 let mut buffer = [0u8; 11];
421 let encoded = val.encode_to_slice(&mut buffer).unwrap();
422 assert_eq!(
423 expected, encoded,
424 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
425 );
426 let decoded = f64::from_der(encoded).unwrap();
427 assert!(
428 (decoded - val).abs() < f64::EPSILON,
429 "wanted: {val}\tgot: {decoded}"
430 );
431 }
432
433 {
434 let val = core::f64::consts::E;
435 let expected = &[
436 0x09, 0x09, 0x80, 0x01, 0x05, 0xbf, 0x0a, 0x8b, 0x14, 0x57, 0x6a,
437 ];
438 let mut buffer = [0u8; 12];
439 let encoded = val.encode_to_slice(&mut buffer).unwrap();
440 assert_eq!(
441 expected, encoded,
442 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
443 );
444 let decoded = f64::from_der(encoded).unwrap();
445 assert!(
446 (decoded - val).abs() < f64::EPSILON,
447 "wanted: {val}\tgot: {decoded}"
448 );
449 }
450 {
451 let val = core::f64::consts::LN_2;
452 let expected = &[
453 0x09, 0x0a, 0x81, 0xff, 0xff, 0x6, 0x2e, 0x42, 0xfe, 0xfa, 0x39, 0xf0,
454 ];
455 let mut buffer = [0u8; 12];
456 let encoded = val.encode_to_slice(&mut buffer).unwrap();
457 assert_eq!(
458 expected, encoded,
459 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
460 );
461 let decoded = f64::from_der(encoded).unwrap();
462 assert!(
463 (decoded - val).abs() < f64::EPSILON,
464 "wanted: {val}\tgot: {decoded}"
465 );
466 }
467 }
468
469 #[test]
470 fn encdec_reasonable_f64() {
471 {
473 let val = 3221417.1584163485;
475 let expected = &[
476 0x9, 0x9, 0x80, 0x15, 0x8, 0x93, 0xd4, 0x94, 0x46, 0xfc, 0xa7,
477 ];
478 let mut buffer = [0u8; 11];
479 let encoded = val.encode_to_slice(&mut buffer).unwrap();
480 assert_eq!(
481 expected, encoded,
482 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
483 );
484 let decoded = f64::from_der(encoded).unwrap();
485 assert!(
486 (decoded - val).abs() < f64::EPSILON,
487 "wanted: {val}\tgot: {decoded}"
488 );
489 }
490
491 {
492 let val = 13364022.365665454;
494 let expected = &[
495 0x09, 0x09, 0x80, 0x17, 0x09, 0x7d, 0x66, 0xcb, 0xb3, 0x88, 0x0b,
496 ];
497 let mut buffer = [0u8; 12];
498 let encoded = val.encode_to_slice(&mut buffer).unwrap();
499 assert_eq!(
500 expected, encoded,
501 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
502 );
503 let decoded = f64::from_der(encoded).unwrap();
504 assert!(
505 (decoded - val).abs() < f64::EPSILON,
506 "wanted: {val}\tgot: {decoded}"
507 );
508 }
509
510 {
511 let val = -32343.132588105735;
513 let expected = &[
514 0x09, 0x09, 0xc0, 0x0e, 0x0f, 0x95, 0xc8, 0x7c, 0x52, 0xd2, 0x7f,
515 ];
516 let mut buffer = [0u8; 12];
517 let encoded = val.encode_to_slice(&mut buffer).unwrap();
518 assert_eq!(
519 expected, encoded,
520 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
521 );
522 let decoded = f64::from_der(encoded).unwrap();
523 assert!(
524 (decoded - val).abs() < f64::EPSILON,
525 "wanted: {val}\tgot: {decoded}"
526 );
527 }
528
529 {
530 let val = -27084.866751869475;
531 let expected = &[
532 0x09, 0x09, 0xc0, 0x0e, 0x0a, 0x73, 0x37, 0x78, 0xdc, 0xd5, 0x4a,
533 ];
534 let mut buffer = [0u8; 12];
535 let encoded = val.encode_to_slice(&mut buffer).unwrap();
536 assert_eq!(
537 expected, encoded,
538 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
539 );
540 let decoded = f64::from_der(encoded).unwrap();
541 assert!(
542 (decoded - val).abs() < f64::EPSILON,
543 "wanted: {val}\tgot: {decoded}"
544 );
545 }
546
547 {
548 let val = -252.28566647111404;
550 let expected = &[
551 0x09, 0x09, 0xc0, 0x07, 0x0f, 0x89, 0x24, 0x2e, 0x02, 0xdf, 0xf5,
552 ];
553 let mut buffer = [0u8; 12];
554 let encoded = val.encode_to_slice(&mut buffer).unwrap();
555 assert_eq!(
556 expected, encoded,
557 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
558 );
559 let decoded = f64::from_der(encoded).unwrap();
560 assert!(
561 (decoded - val).abs() < f64::EPSILON,
562 "wanted: {val}\tgot: {decoded}"
563 );
564 }
565
566 {
567 let val = -14.399709612928548;
568 let expected = &[
569 0x09, 0x09, 0xc0, 0x03, 0x0c, 0xcc, 0xa6, 0xbd, 0x06, 0xd9, 0x92,
570 ];
571 let mut buffer = [0u8; 12];
572 let encoded = val.encode_to_slice(&mut buffer).unwrap();
573 assert_eq!(
574 expected, encoded,
575 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
576 );
577 let decoded = f64::from_der(encoded).unwrap();
578 assert!(
579 (decoded - val).abs() < f64::EPSILON,
580 "wanted: {val}\tgot: {decoded}"
581 );
582 }
583
584 {
585 let val = -0.08340570261832964;
586 let expected = &[
587 0x09, 0x0a, 0xc1, 0xff, 0xfc, 0x05, 0x5a, 0x13, 0x7d, 0x0b, 0xae, 0x3d,
588 ];
589 let mut buffer = [0u8; 12];
590 let encoded = val.encode_to_slice(&mut buffer).unwrap();
591 assert_eq!(
592 expected, encoded,
593 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
594 );
595 let decoded = f64::from_der(encoded).unwrap();
596 assert!(
597 (decoded - val).abs() < f64::EPSILON,
598 "wanted: {val}\tgot: {decoded}"
599 );
600 }
601
602 {
603 let val = 0.00536851453803701;
604 let expected = &[
605 0x09, 0x0a, 0x81, 0xff, 0xf8, 0x05, 0xfd, 0x4b, 0xa5, 0xe7, 0x4c, 0x93,
606 ];
607 let mut buffer = [0u8; 12];
608 let encoded = val.encode_to_slice(&mut buffer).unwrap();
609 assert_eq!(
610 expected, encoded,
611 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
612 );
613 let decoded = f64::from_der(encoded).unwrap();
614 assert!(
615 (decoded - val).abs() < f64::EPSILON,
616 "wanted: {val}\tgot: {decoded}"
617 );
618 }
619
620 {
621 let val = 0.00045183525648866433;
622 let expected = &[
623 0x09, 0x0a, 0x81, 0xff, 0xf4, 0x0d, 0x9c, 0x89, 0xa6, 0x59, 0x33, 0x39,
624 ];
625 let mut buffer = [0u8; 12];
626 let encoded = val.encode_to_slice(&mut buffer).unwrap();
627 assert_eq!(
628 expected, encoded,
629 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
630 );
631 let decoded = f64::from_der(encoded).unwrap();
632 assert!(
633 (decoded - val).abs() < f64::EPSILON,
634 "wanted: {val}\tgot: {decoded}"
635 );
636 }
637
638 {
639 let val = 0.000033869092002682955;
640 let expected = &[
641 0x09, 0x0a, 0x81, 0xff, 0xf1, 0x01, 0xc1, 0xd5, 0x23, 0xd5, 0x54, 0x7c,
642 ];
643 let mut buffer = [0u8; 12];
644 let encoded = val.encode_to_slice(&mut buffer).unwrap();
645 assert_eq!(
646 expected, encoded,
647 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
648 );
649 let decoded = f64::from_der(encoded).unwrap();
650 assert!(
651 (decoded - val).abs() < f64::EPSILON,
652 "wanted: {val}\tgot: {decoded}"
653 );
654 }
655
656 {
657 let val = 0.0000011770891033600088;
658 let expected = &[
659 0x09, 0x0a, 0x81, 0xff, 0xec, 0x03, 0xbf, 0x8f, 0x27, 0xf4, 0x62, 0x56,
660 ];
661 let mut buffer = [0u8; 12];
662 let encoded = val.encode_to_slice(&mut buffer).unwrap();
663 assert_eq!(
664 expected, encoded,
665 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
666 );
667 let decoded = f64::from_der(encoded).unwrap();
668 assert!(
669 (decoded - val).abs() < f64::EPSILON,
670 "wanted: {val}\tgot: {decoded}"
671 );
672 }
673
674 {
675 let val = 0.00000005549514041997082;
676 let expected = &[
677 0x09, 0x0a, 0x81, 0xff, 0xe7, 0x0d, 0xcb, 0x31, 0xab, 0x6e, 0xb8, 0xd7,
678 ];
679 let mut buffer = [0u8; 12];
680 let encoded = val.encode_to_slice(&mut buffer).unwrap();
681 assert_eq!(
682 expected, encoded,
683 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
684 );
685 let decoded = f64::from_der(encoded).unwrap();
686 assert!(
687 (decoded - val).abs() < f64::EPSILON,
688 "wanted: {val}\tgot: {decoded}"
689 );
690 }
691
692 {
693 let val = 0.0000000012707044685547803;
694 let expected = &[
695 0x09, 0x0a, 0x81, 0xff, 0xe2, 0x05, 0xd4, 0x9e, 0x0a, 0xf2, 0xff, 0x1f,
696 ];
697 let mut buffer = [0u8; 12];
698 let encoded = val.encode_to_slice(&mut buffer).unwrap();
699 assert_eq!(
700 expected, encoded,
701 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
702 );
703 let decoded = f64::from_der(encoded).unwrap();
704 assert!(
705 (decoded - val).abs() < f64::EPSILON,
706 "wanted: {val}\tgot: {decoded}"
707 );
708 }
709
710 {
711 let val = 0.00000000002969611878378562;
712 let expected = &[
713 0x09, 0x09, 0x81, 0xff, 0xdd, 0x53, 0x5b, 0x6f, 0x97, 0xee, 0xb6,
714 ];
715 let mut buffer = [0u8; 11];
716 let encoded = val.encode_to_slice(&mut buffer).unwrap();
717 assert_eq!(
718 expected, encoded,
719 "invalid encoding of {val}:\ngot {encoded:x?}\nwant: {expected:x?}"
720 );
721 let decoded = f64::from_der(encoded).unwrap();
722 assert!(
723 (decoded - val).abs() < f64::EPSILON,
724 "wanted: {val}\tgot: {decoded}"
725 );
726 }
727 }
728
729 #[test]
730 fn reject_non_canonical() {
731 assert!(f64::from_der(&[0x09, 0x81, 0x00]).is_err());
732 }
733
734 #[test]
735 fn encdec_f64() {
736 use super::{decode_f64, encode_f64};
737 for val in [
739 1.0,
740 0.1,
741 -0.1,
742 -1.0,
743 0.0,
744 f64::MIN_POSITIVE,
745 f64::MAX,
746 f64::MIN,
747 core::f64::consts::PI,
748 -core::f64::consts::PI,
749 951.2357864,
750 -951.2357864,
751 ] {
752 let (s, e, m) = decode_f64(val);
753 let val2 = encode_f64(s, e, m);
754 assert!(
755 (val - val2).abs() < f64::EPSILON,
756 "fail - want {val}\tgot {val2}"
757 );
758 }
759 }
760
761 #[test]
762 fn validation_cases() {
763 {
774 let expect = 10.0;
775 let testcase = &[0x09, 0x05, 0x03, 0x31, 0x2E, 0x45, 0x31];
776 let decoded = f64::from_der(testcase).unwrap();
777 assert!(
778 (decoded - expect).abs() < f64::EPSILON,
779 "wanted: {expect}\tgot: {decoded}"
780 );
781 }
782 {
783 let expect = 100.0;
784 let testcase = &[0x09, 0x05, 0x03, 0x31, 0x2E, 0x45, 0x32];
785 let decoded = f64::from_der(testcase).unwrap();
786 assert!(
787 (decoded - expect).abs() < f64::EPSILON,
788 "wanted: {expect}\tgot: {decoded}"
789 );
790 }
791 {
792 let expect = 101.0;
793 let testcase = &[0x09, 0x08, 0x03, 0x31, 0x30, 0x31, 0x2E, 0x45, 0x2B, 0x30];
794 let decoded = f64::from_der(testcase).unwrap();
795 assert!(
796 (decoded - expect).abs() < f64::EPSILON,
797 "wanted: {expect}\tgot: {decoded}"
798 );
799 }
800 {
801 let expect = 101.0;
802 let testcase = &[0x09, 0x08, 0x03, 0x31, 0x30, 0x31, 0x2E, 0x45, 0x2B, 0x30];
803 let decoded = f64::from_der(testcase).unwrap();
804 assert!(
805 (decoded - expect).abs() < f64::EPSILON,
806 "wanted: {expect}\tgot: {decoded}"
807 );
808 }
809 {
810 let expect = 0.0;
811 let testcase = &[0x09, 0x00];
812 let decoded = f64::from_der(testcase).unwrap();
813 assert!(
814 (decoded - expect).abs() < f64::EPSILON,
815 "wanted: {expect}\tgot: {decoded}"
816 );
817 }
818 {
819 let expect = 951.2357864;
820 let testcase = &[
821 0x09, 0x0F, 0x03, 0x39, 0x35, 0x31, 0x32, 0x33, 0x35, 0x37, 0x38, 0x36, 0x34, 0x2E,
822 0x45, 0x2D, 0x37,
823 ];
824 let decoded = f64::from_der(testcase).unwrap();
825 assert!(
826 (decoded - expect).abs() < f64::EPSILON,
827 "wanted: {expect}\tgot: {decoded}"
828 );
829 }
830 {
832 let expect = -10.0;
833 let testcase = &[0x09, 0x06, 0x03, 0x2D, 0x31, 0x2E, 0x45, 0x31];
834 let decoded = f64::from_der(testcase).unwrap();
835 assert!(
836 (decoded - expect).abs() < f64::EPSILON,
837 "wanted: {expect}\tgot: {decoded}"
838 );
839 }
840 {
841 let expect = -100.0;
842 let testcase = &[0x09, 0x06, 0x03, 0x2D, 0x31, 0x2E, 0x45, 0x32];
843 let decoded = f64::from_der(testcase).unwrap();
844 assert!(
845 (decoded - expect).abs() < f64::EPSILON,
846 "wanted: {expect}\tgot: {decoded}"
847 );
848 }
849 {
850 let expect = -101.0;
851 let testcase = &[
852 0x09, 0x09, 0x03, 0x2D, 0x31, 0x30, 0x31, 0x2E, 0x45, 0x2B, 0x30,
853 ];
854 let decoded = f64::from_der(testcase).unwrap();
855 assert!(
856 (decoded - expect).abs() < f64::EPSILON,
857 "wanted: {expect}\tgot: {decoded}"
858 );
859 }
860 {
861 let expect = -0.5;
862 let testcase = &[0x09, 0x07, 0x03, 0x2D, 0x35, 0x2E, 0x45, 0x2D, 0x31];
863 let decoded = f64::from_der(testcase).unwrap();
864 assert!(
865 (decoded - expect).abs() < f64::EPSILON,
866 "wanted: {expect}\tgot: {decoded}"
867 );
868 }
869 {
870 let expect = -0.0;
871 let testcase = &[0x09, 0x03, 0x01, 0x2D, 0x30];
872 let decoded = f64::from_der(testcase).unwrap();
873 assert!(
874 (decoded - expect).abs() < f64::EPSILON,
875 "wanted: {expect}\tgot: {decoded}"
876 );
877 }
878 {
879 let expect = -951.2357864;
881 let testcase = &[
882 0x09, 0x10, 0x03, 0x2D, 0x39, 0x35, 0x31, 0x32, 0x33, 0x35, 0x37, 0x38, 0x36, 0x34,
883 0x2E, 0x45, 0x2D, 0x37,
884 ];
885 let decoded = f64::from_der(testcase).unwrap();
886 assert!(
887 (decoded - expect).abs() < f64::EPSILON,
888 "wanted: {expect}\tgot: {decoded}"
889 );
890 }
891 }
892}