@@ -424,11 +424,71 @@ 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, i32fx8} ;
438
+ use core:: { fmt:: Write , str} ;
439
+
440
+ struct WriteBuf < const N : usize > ( [ u8 ; N ] , usize ) ;
441
+ impl < ' a , const N : usize > Default for WriteBuf < N > {
442
+ fn default ( ) -> Self {
443
+ Self ( [ 0u8 ; N ] , 0 )
444
+ }
445
+ }
446
+ impl < const N : usize > Write for WriteBuf < N > {
447
+ fn write_str ( & mut self , s : & str ) -> core:: fmt:: Result {
448
+ let src = s. as_bytes ( ) ;
449
+ let len = ( self . 0 . len ( ) - self . 1 ) . min ( src. len ( ) ) ;
450
+ self . 0 [ self . 1 ..self . 1 + len] . copy_from_slice ( & src[ ..len] ) ;
451
+ self . 1 += len;
452
+ if len < src. len ( ) {
453
+ Err ( core:: fmt:: Error )
454
+ } else {
455
+ Ok ( ( ) )
456
+ }
457
+ }
458
+ }
459
+ impl < const N : usize > WriteBuf < N > {
460
+ fn take ( & mut self ) -> & str {
461
+ let len = self . 1 ;
462
+ self . 1 = 0 ;
463
+ str:: from_utf8 ( & self . 0 [ ..len] ) . unwrap ( )
464
+ }
465
+ }
466
+
467
+ #[ test_case]
468
+ fn decimal_display ( ) {
469
+ let mut wbuf = WriteBuf :: < 16 > :: default ( ) ;
470
+
471
+ let x = i32fx8:: from_bits ( 0x12345678 ) ;
472
+
473
+ write ! ( & mut wbuf, "{x}" ) . unwrap ( ) ;
474
+ assert_eq ! ( wbuf. take( ) , "1193046.468" ) ;
475
+
476
+ write ! ( & mut wbuf, "{x:9.1}" ) . unwrap ( ) ;
477
+ assert_eq ! ( wbuf. take( ) , " 1193046.4" ) ;
478
+
479
+ write ! ( & mut wbuf, "{x:1.6}" ) . unwrap ( ) ;
480
+ assert_eq ! ( wbuf. take( ) , "1193046.468750" ) ;
481
+
482
+ let x = x. neg ( ) ;
483
+ write ! ( & mut wbuf, "{x}" ) . unwrap ( ) ;
484
+ assert_eq ! ( wbuf. take( ) , "-1193046.468" ) ;
485
+
486
+ let x = i16fx14:: from_bits ( 0x6544 as i16 ) ;
487
+ write ! ( & mut wbuf, "{x}" ) . unwrap ( ) ;
488
+ assert_eq ! ( wbuf. take( ) , "1.58227" ) ;
489
+
490
+ let x = x. neg ( ) ;
491
+ write ! ( & mut wbuf, "{x:.10}" ) . unwrap ( ) ;
492
+ assert_eq ! ( wbuf. take( ) , "-1.5822753906" ) ;
493
+ }
494
+ }
0 commit comments