@@ -424,11 +424,74 @@ fn fixed_fmt_abs<const B: u32>(
424
424
let width = f. width ( ) . unwrap_or ( 0 ) ;
425
425
let precision = f. precision ( ) . unwrap_or ( const { ( ( B as usize ) + 1 ) / 3 } ) ;
426
426
let fract = abs & ( ( 1 << B ) - 1 ) ;
427
- let fract_dec = fract
428
- . checked_mul ( 10u32 . pow ( precision as u32 ) )
429
- . map ( |x| x >> B )
430
- . unwrap_or_else ( || {
431
- ( fract as u64 * 10u64 . pow ( precision as u32 ) >> B ) as u32
432
- } ) ;
427
+ let fract_dec = 10u32
428
+ . checked_pow ( precision as u32 )
429
+ . and_then ( |digits| fract. checked_mul ( digits) )
430
+ . map ( |x| ( x >> B ) as u64 )
431
+ . unwrap_or_else ( || ( fract as u64 * 10u64 . pow ( precision as u32 ) >> B ) ) ;
433
432
write ! ( f, "{:width$}.{:0precision$}" , abs >> B , fract_dec)
434
433
}
434
+
435
+ #[ cfg( test) ]
436
+ mod test {
437
+ use crate :: fixed:: i16fx14;
438
+
439
+ use super :: i32fx8;
440
+ use core:: { fmt:: Write , str} ;
441
+
442
+ struct WriteBuf < ' a > ( & ' a mut [ u8 ] , usize ) ;
443
+ impl < ' a > From < & ' a mut [ u8 ] > for WriteBuf < ' a > {
444
+ fn from ( value : & ' a mut [ u8 ] ) -> Self {
445
+ Self ( value, 0 )
446
+ }
447
+ }
448
+ impl Write for WriteBuf < ' _ > {
449
+ fn write_str ( & mut self , s : & str ) -> core:: fmt:: Result {
450
+ let src = s. as_bytes ( ) ;
451
+ let len = ( self . 0 . len ( ) - self . 1 ) . min ( src. len ( ) ) ;
452
+ self . 0 [ self . 1 ..self . 1 + len] . copy_from_slice ( & src[ ..len] ) ;
453
+ self . 1 += len;
454
+ if len < src. len ( ) {
455
+ Err ( core:: fmt:: Error )
456
+ } else {
457
+ Ok ( ( ) )
458
+ }
459
+ }
460
+ }
461
+ impl WriteBuf < ' _ > {
462
+ fn take ( & mut self ) -> & str {
463
+ let len = self . 1 ;
464
+ self . 1 = 0 ;
465
+ str:: from_utf8 ( & self . 0 [ ..len] ) . unwrap ( )
466
+ }
467
+ }
468
+
469
+ #[ test_case]
470
+ fn decimal_display ( ) {
471
+ let mut buf = [ 0u8 ; 16 ] ;
472
+ let mut wbuf = WriteBuf :: from ( & mut buf[ ..] ) ;
473
+
474
+ let x = i32fx8:: from_bits ( 0x12345678 ) ;
475
+
476
+ write ! ( & mut wbuf, "{x}" ) . unwrap ( ) ;
477
+ assert_eq ! ( wbuf. take( ) , "1193046.468" ) ;
478
+
479
+ write ! ( & mut wbuf, "{x:9.1}" ) . unwrap ( ) ;
480
+ assert_eq ! ( wbuf. take( ) , " 1193046.4" ) ;
481
+
482
+ write ! ( & mut wbuf, "{x:1.6}" ) . unwrap ( ) ;
483
+ assert_eq ! ( wbuf. take( ) , "1193046.468750" ) ;
484
+
485
+ let x = x. neg ( ) ;
486
+ write ! ( & mut wbuf, "{x}" ) . unwrap ( ) ;
487
+ assert_eq ! ( wbuf. take( ) , "-1193046.468" ) ;
488
+
489
+ let x = i16fx14:: from_bits ( 0x6544 as i16 ) ;
490
+ write ! ( & mut wbuf, "{x}" ) . unwrap ( ) ;
491
+ assert_eq ! ( wbuf. take( ) , "1.58227" ) ;
492
+
493
+ let x = x. neg ( ) ;
494
+ write ! ( & mut wbuf, "{x:.10}" ) . unwrap ( ) ;
495
+ assert_eq ! ( wbuf. take( ) , "-1.5822753906" ) ;
496
+ }
497
+ }
0 commit comments