1+ // This file is part of the minifloat project.
2+ //
3+ // Copyright (C) 2025 Chen-Pang He <jdh8@skymizer.com>
4+ //
5+ // This Source Code Form is subject to the terms of the Mozilla
6+ // Public License v. 2.0. If a copy of the MPL was not distributed
7+ // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
8+
19use core:: fmt:: Debug ;
210use minifloat:: example:: * ;
311use minifloat:: { minifloat, Minifloat , NanStyle } ;
@@ -22,7 +30,7 @@ const fn bit_mask(width: u32) -> Mask {
2230 if width == 0 {
2331 0
2432 } else {
25- Mask :: MAX >> ( Mask :: BITS - width)
33+ ! 0 >> ( Mask :: BITS - width)
2634 }
2735}
2836
@@ -49,59 +57,79 @@ fn same_mini<T: Minifloat>(x: T, y: T) -> bool {
4957 x. to_bits ( ) == y. to_bits ( ) || x. is_nan ( ) && y. is_nan ( )
5058}
5159
52- /// Iterate over all representations in a [`Minifloat`]
60+ /// Iterate over all representations of a minifloat type
5361fn for_all < T : Minifloat > ( f : impl Fn ( T ) -> bool ) -> bool
5462where
5563 Mask : AsPrimitive < T :: Bits > ,
5664{
5765 ( 0 ..=bit_mask ( T :: BITWIDTH ) ) . all ( |bits| f ( T :: from_bits ( bits. as_ ( ) ) ) )
5866}
5967
60- fn check_equality < T : Minifloat + Debug > ( ) -> bool
61- where
62- Mask : AsPrimitive < T :: Bits > ,
63- {
64- let fixed_point = if T :: M == 0 { 2.0 } else { 3.0 } ;
65- assert ! ( same_f32( T :: from_f32( fixed_point) . to_f32( ) , fixed_point) ) ;
68+ /// Wrapper trait for checking properties of minifloats
69+ ///
70+ /// This trait helps building generic test infrastructure. Opposed to generic
71+ /// functions, traits can work as parameters.
72+ trait Check {
73+ /// Check properties of a minifloat type
74+ fn check < T : Minifloat + Debug > ( ) -> bool
75+ where
76+ Mask : AsPrimitive < T :: Bits > ;
77+
78+ /// Test typical minifloats
79+ fn test ( ) {
80+ assert ! ( Self :: check:: <F8E2M5 >( ) ) ;
81+ assert ! ( Self :: check:: <F8E2M5FN >( ) ) ;
82+ assert ! ( Self :: check:: <F8E2M5FNUZ >( ) ) ;
83+
84+ assert ! ( Self :: check:: <F8E3M4 >( ) ) ;
85+ assert ! ( Self :: check:: <F8E3M4FN >( ) ) ;
86+ assert ! ( Self :: check:: <F8E3M4FNUZ >( ) ) ;
87+
88+ assert ! ( Self :: check:: <F8E4M3 >( ) ) ;
89+ assert ! ( Self :: check:: <F8E4M3FN >( ) ) ;
90+ assert ! ( Self :: check:: <F8E4M3FNUZ >( ) ) ;
91+
92+ assert ! ( Self :: check:: <F8E4M3B11 >( ) ) ;
93+ assert ! ( Self :: check:: <F8E4M3B11FN >( ) ) ;
94+ assert ! ( Self :: check:: <F8E4M3B11FNUZ >( ) ) ;
95+
96+ assert ! ( Self :: check:: <F8E5M2 >( ) ) ;
97+ assert ! ( Self :: check:: <F8E5M2FN >( ) ) ;
98+ assert ! ( Self :: check:: <F8E5M2FNUZ >( ) ) ;
99+ }
100+ }
66101
67- let fixed_point = f64:: from ( fixed_point) ;
68- assert ! ( same_f64( T :: from_f64( fixed_point) . to_f64( ) , fixed_point) ) ;
102+ struct CheckEquality ;
69103
70- assert_eq ! ( T :: from_f32( 0.0 ) , T :: from_f32( -0.0 ) ) ;
71- assert_eq ! (
72- same_mini( T :: from_f32( 0.0 ) , T :: from_f32( -0.0 ) ) ,
73- T :: N == NanStyle :: FNUZ
74- ) ;
104+ impl Check for CheckEquality {
105+ fn check < T : Minifloat + Debug > ( ) -> bool
106+ where
107+ Mask : AsPrimitive < T :: Bits > ,
108+ {
109+ let fixed_point = if T :: M == 0 { 2.0 } else { 3.0 } ;
110+ assert ! ( same_f32( T :: from_f32( fixed_point) . to_f32( ) , fixed_point) ) ;
75111
76- assert ! ( T :: NAN . is_nan( ) ) ;
77- assert ! ( T :: from_f32( f32 :: NAN ) . is_nan( ) ) ;
78- assert ! ( T :: from_f64( f64 :: NAN ) . is_nan( ) ) ;
112+ let fixed_point = f64:: from ( fixed_point) ;
113+ assert ! ( same_f64( T :: from_f64( fixed_point) . to_f64( ) , fixed_point) ) ;
79114
80- assert ! ( T :: NAN . ne( & T :: NAN ) ) ;
81- assert ! ( same_mini( T :: NAN , T :: NAN ) ) ;
115+ assert_eq ! ( T :: from_f32( 0.0 ) , T :: from_f32( -0.0 ) ) ;
116+ assert_eq ! (
117+ same_mini( T :: from_f32( 0.0 ) , T :: from_f32( -0.0 ) ) ,
118+ T :: N == NanStyle :: FNUZ
119+ ) ;
82120
83- for_all :: < T > ( |x| x. ne ( & x) == x. is_nan ( ) )
121+ assert ! ( T :: NAN . is_nan( ) ) ;
122+ assert ! ( T :: from_f32( f32 :: NAN ) . is_nan( ) ) ;
123+ assert ! ( T :: from_f64( f64 :: NAN ) . is_nan( ) ) ;
124+
125+ assert ! ( T :: NAN . ne( & T :: NAN ) ) ;
126+ assert ! ( same_mini( T :: NAN , T :: NAN ) ) ;
127+
128+ for_all :: < T > ( |x| x. ne ( & x) == x. is_nan ( ) )
129+ }
84130}
85131
86132#[ test]
87133fn test_equality ( ) {
88- assert ! ( check_equality:: <F8E2M5 >( ) ) ;
89- assert ! ( check_equality:: <F8E2M5FN >( ) ) ;
90- assert ! ( check_equality:: <F8E2M5FNUZ >( ) ) ;
91-
92- assert ! ( check_equality:: <F8E3M4 >( ) ) ;
93- assert ! ( check_equality:: <F8E3M4FN >( ) ) ;
94- assert ! ( check_equality:: <F8E3M4FNUZ >( ) ) ;
95-
96- assert ! ( check_equality:: <F8E4M3 >( ) ) ;
97- assert ! ( check_equality:: <F8E4M3FN >( ) ) ;
98- assert ! ( check_equality:: <F8E4M3FNUZ >( ) ) ;
99-
100- assert ! ( check_equality:: <F8E4M3B11 >( ) ) ;
101- assert ! ( check_equality:: <F8E4M3B11FN >( ) ) ;
102- assert ! ( check_equality:: <F8E4M3B11FNUZ >( ) ) ;
103-
104- assert ! ( check_equality:: <F8E5M2 >( ) ) ;
105- assert ! ( check_equality:: <F8E5M2FN >( ) ) ;
106- assert ! ( check_equality:: <F8E5M2FNUZ >( ) ) ;
134+ CheckEquality :: test ( ) ;
107135}
0 commit comments