@@ -10,6 +10,63 @@ fn assert_eq<T: PartialEq + Debug>(x: T, y: T) {
10
10
assert_eq ! ( x, y) ;
11
11
}
12
12
13
+ trait FloatToInt < Int > : Copy {
14
+ fn cast ( self ) -> Int ;
15
+ unsafe fn cast_unchecked ( self ) -> Int ;
16
+ }
17
+
18
+ impl FloatToInt < i8 > for f32 {
19
+ fn cast ( self ) -> i8 { self as _ }
20
+ unsafe fn cast_unchecked ( self ) -> i8 { self . to_int_unchecked ( ) }
21
+ }
22
+ impl FloatToInt < i32 > for f32 {
23
+ fn cast ( self ) -> i32 { self as _ }
24
+ unsafe fn cast_unchecked ( self ) -> i32 { self . to_int_unchecked ( ) }
25
+ }
26
+ impl FloatToInt < u32 > for f32 {
27
+ fn cast ( self ) -> u32 { self as _ }
28
+ unsafe fn cast_unchecked ( self ) -> u32 { self . to_int_unchecked ( ) }
29
+ }
30
+ impl FloatToInt < i64 > for f32 {
31
+ fn cast ( self ) -> i64 { self as _ }
32
+ unsafe fn cast_unchecked ( self ) -> i64 { self . to_int_unchecked ( ) }
33
+ }
34
+ impl FloatToInt < u64 > for f32 {
35
+ fn cast ( self ) -> u64 { self as _ }
36
+ unsafe fn cast_unchecked ( self ) -> u64 { self . to_int_unchecked ( ) }
37
+ }
38
+
39
+ impl FloatToInt < i8 > for f64 {
40
+ fn cast ( self ) -> i8 { self as _ }
41
+ unsafe fn cast_unchecked ( self ) -> i8 { self . to_int_unchecked ( ) }
42
+ }
43
+ impl FloatToInt < i32 > for f64 {
44
+ fn cast ( self ) -> i32 { self as _ }
45
+ unsafe fn cast_unchecked ( self ) -> i32 { self . to_int_unchecked ( ) }
46
+ }
47
+ impl FloatToInt < u32 > for f64 {
48
+ fn cast ( self ) -> u32 { self as _ }
49
+ unsafe fn cast_unchecked ( self ) -> u32 { self . to_int_unchecked ( ) }
50
+ }
51
+ impl FloatToInt < i64 > for f64 {
52
+ fn cast ( self ) -> i64 { self as _ }
53
+ unsafe fn cast_unchecked ( self ) -> i64 { self . to_int_unchecked ( ) }
54
+ }
55
+ impl FloatToInt < u64 > for f64 {
56
+ fn cast ( self ) -> u64 { self as _ }
57
+ unsafe fn cast_unchecked ( self ) -> u64 { self . to_int_unchecked ( ) }
58
+ }
59
+
60
+ /// Test this cast both via `as` and via `approx_unchecked` (i.e., it must not saturate).
61
+ #[ track_caller]
62
+ #[ inline( never) ]
63
+ fn test_cast < F , I > ( x : F , y : I )
64
+ where F : FloatToInt < I > , I : PartialEq + Debug
65
+ {
66
+ assert_eq ! ( x. cast( ) , y) ;
67
+ assert_eq ! ( unsafe { x. cast_unchecked( ) } , y) ;
68
+ }
69
+
13
70
fn main ( ) {
14
71
basic ( ) ;
15
72
casts ( ) ;
@@ -50,19 +107,23 @@ fn basic() {
50
107
}
51
108
52
109
fn casts ( ) {
110
+ // f32 -> i8
111
+ test_cast :: < f32 , i8 > ( 127.99 , 127 ) ;
112
+ test_cast :: < f32 , i8 > ( -128.99 , -128 ) ;
113
+
53
114
// f32 -> i32
54
- assert_eq :: < i32 > ( 0.0f32 as i32 , 0 ) ;
55
- assert_eq :: < i32 > ( -0.0f32 as i32 , 0 ) ;
56
- assert_eq :: < i32 > ( /*0x1p-149*/ f32:: from_bits ( 0x00000001 ) as i32 , 0 ) ;
57
- assert_eq :: < i32 > ( /*-0x1p-149*/ f32:: from_bits ( 0x80000001 ) as i32 , 0 ) ;
58
- assert_eq :: < i32 > ( /*0x1.19999ap+0*/ f32:: from_bits ( 0x3f8ccccd ) as i32 , 1 ) ;
59
- assert_eq :: < i32 > ( /*-0x1.19999ap+0*/ f32:: from_bits ( 0xbf8ccccd ) as i32 , -1 ) ;
60
- assert_eq :: < i32 > ( 1.9f32 as i32 , 1 ) ;
61
- assert_eq :: < i32 > ( -1.9f32 as i32 , -1 ) ;
62
- assert_eq :: < i32 > ( 5.0f32 as i32 , 5 ) ;
63
- assert_eq :: < i32 > ( -5.0f32 as i32 , -5 ) ;
64
- assert_eq :: < i32 > ( 2147483520.0f32 as i32 , 2147483520 ) ;
65
- assert_eq :: < i32 > ( -2147483648.0f32 as i32 , -2147483648 ) ;
115
+ test_cast :: < f32 , i32 > ( 0.0 , 0 ) ;
116
+ test_cast :: < f32 , i32 > ( -0.0 , 0 ) ;
117
+ test_cast :: < f32 , i32 > ( /*0x1p-149*/ f32:: from_bits ( 0x00000001 ) , 0 ) ;
118
+ test_cast :: < f32 , i32 > ( /*-0x1p-149*/ f32:: from_bits ( 0x80000001 ) , 0 ) ;
119
+ test_cast :: < f32 , i32 > ( /*0x1.19999ap+0*/ f32:: from_bits ( 0x3f8ccccd ) , 1 ) ;
120
+ test_cast :: < f32 , i32 > ( /*-0x1.19999ap+0*/ f32:: from_bits ( 0xbf8ccccd ) , -1 ) ;
121
+ test_cast :: < f32 , i32 > ( 1.9 , 1 ) ;
122
+ test_cast :: < f32 , i32 > ( -1.9 , -1 ) ;
123
+ test_cast :: < f32 , i32 > ( 5.0 , 5 ) ;
124
+ test_cast :: < f32 , i32 > ( -5.0 , -5 ) ;
125
+ test_cast :: < f32 , i32 > ( 2147483520.0 , 2147483520 ) ;
126
+ test_cast :: < f32 , i32 > ( -2147483648.0 , -2147483648 ) ;
66
127
// unrepresentable casts
67
128
assert_eq :: < i32 > ( 2147483648.0f32 as i32 , i32:: MAX ) ;
68
129
assert_eq :: < i32 > ( -2147483904.0f32 as i32 , i32:: MIN ) ;
@@ -74,19 +135,19 @@ fn casts() {
74
135
assert_eq :: < i32 > ( ( -f32:: NAN ) as i32 , 0 ) ;
75
136
76
137
// f32 -> u32
77
- assert_eq :: < u32 > ( 0.0f32 as u32 , 0 ) ;
78
- assert_eq :: < u32 > ( -0.0f32 as u32 , 0 ) ;
79
- assert_eq :: < u32 > ( /*0x1p-149*/ f32:: from_bits ( 0x1 ) as u32 , 0 ) ;
80
- assert_eq :: < u32 > ( /*-0x1p-149*/ f32:: from_bits ( 0x80000001 ) as u32 , 0 ) ;
81
- assert_eq :: < u32 > ( /*0x1.19999ap+0*/ f32:: from_bits ( 0x3f8ccccd ) as u32 , 1 ) ;
82
- assert_eq :: < u32 > ( 1.9f32 as u32 , 1 ) ;
83
- assert_eq :: < u32 > ( 5.0f32 as u32 , 5 ) ;
84
- assert_eq :: < u32 > ( 2147483648.0f32 as u32 , 0x8000_0000 ) ;
85
- assert_eq :: < u32 > ( 4294967040.0f32 as u32 , 0u32 . wrapping_sub ( 256 ) ) ;
86
- assert_eq :: < u32 > ( /*-0x1.ccccccp-1*/ f32:: from_bits ( 0xbf666666 ) as u32 , 0 ) ;
87
- assert_eq :: < u32 > ( /*-0x1.fffffep-1*/ f32:: from_bits ( 0xbf7fffff ) as u32 , 0 ) ;
88
- assert_eq :: < u32 > ( ( u32:: MAX -127 ) as f32 as u32 , u32:: MAX ) ; // rounding loss
89
- assert_eq :: < u32 > ( ( u32:: MAX -128 ) as f32 as u32 , u32:: MAX -255 ) ; // rounding loss
138
+ test_cast :: < f32 , u32 > ( 0.0 , 0 ) ;
139
+ test_cast :: < f32 , u32 > ( -0.0 , 0 ) ;
140
+ test_cast :: < f32 , u32 > ( /*0x1p-149*/ f32:: from_bits ( 0x1 ) , 0 ) ;
141
+ test_cast :: < f32 , u32 > ( /*-0x1p-149*/ f32:: from_bits ( 0x80000001 ) , 0 ) ;
142
+ test_cast :: < f32 , u32 > ( /*0x1.19999ap+0*/ f32:: from_bits ( 0x3f8ccccd ) , 1 ) ;
143
+ test_cast :: < f32 , u32 > ( 1.9 , 1 ) ;
144
+ test_cast :: < f32 , u32 > ( 5.0 , 5 ) ;
145
+ test_cast :: < f32 , u32 > ( 2147483648.0 , 0x8000_0000 ) ;
146
+ test_cast :: < f32 , u32 > ( 4294967040.0 , 0u32 . wrapping_sub ( 256 ) ) ;
147
+ test_cast :: < f32 , u32 > ( /*-0x1.ccccccp-1*/ f32:: from_bits ( 0xbf666666 ) , 0 ) ;
148
+ test_cast :: < f32 , u32 > ( /*-0x1.fffffep-1*/ f32:: from_bits ( 0xbf7fffff ) , 0 ) ;
149
+ test_cast :: < f32 , u32 > ( ( u32:: MAX -127 ) as f32 , u32:: MAX ) ; // rounding loss
150
+ test_cast :: < f32 , u32 > ( ( u32:: MAX -128 ) as f32 , u32:: MAX -255 ) ; // rounding loss
90
151
// unrepresentable casts
91
152
assert_eq :: < u32 > ( 4294967296.0f32 as u32 , u32:: MAX ) ;
92
153
assert_eq :: < u32 > ( -5.0f32 as u32 , 0 ) ;
@@ -98,40 +159,44 @@ fn casts() {
98
159
assert_eq :: < u32 > ( ( -f32:: NAN ) as u32 , 0 ) ;
99
160
100
161
// f32 -> i64
101
- assert_eq :: < i64 > ( 4294967296.0f32 as i64 , 4294967296 ) ;
102
- assert_eq :: < i64 > ( -4294967296.0f32 as i64 , -4294967296 ) ;
103
- assert_eq :: < i64 > ( 9223371487098961920.0f32 as i64 , 9223371487098961920 ) ;
104
- assert_eq :: < i64 > ( -9223372036854775808.0f32 as i64 , -9223372036854775808 ) ;
162
+ test_cast :: < f32 , i64 > ( 4294967296.0 , 4294967296 ) ;
163
+ test_cast :: < f32 , i64 > ( -4294967296.0 , -4294967296 ) ;
164
+ test_cast :: < f32 , i64 > ( 9223371487098961920.0 , 9223371487098961920 ) ;
165
+ test_cast :: < f32 , i64 > ( -9223372036854775808.0 , -9223372036854775808 ) ;
166
+
167
+ // f64 -> i8
168
+ test_cast :: < f64 , i8 > ( 127.99 , 127 ) ;
169
+ test_cast :: < f64 , i8 > ( -128.99 , -128 ) ;
105
170
106
171
// f64 -> i32
107
- assert_eq :: < i32 > ( 0.0f64 as i32 , 0 ) ;
108
- assert_eq :: < i32 > ( -0.0f64 as i32 , 0 ) ;
109
- assert_eq :: < i32 > ( /*0x1.199999999999ap+0*/ f64:: from_bits ( 0x3ff199999999999a ) as i32 , 1 ) ;
110
- assert_eq :: < i32 > ( /*-0x1.199999999999ap+0*/ f64:: from_bits ( 0xbff199999999999a ) as i32 , -1 ) ;
111
- assert_eq :: < i32 > ( 1.9f64 as i32 , 1 ) ;
112
- assert_eq :: < i32 > ( -1.9f64 as i32 , -1 ) ;
113
- assert_eq :: < i32 > ( 1e8f64 as i32 , 100_000_000 ) ;
114
- assert_eq :: < i32 > ( 2147483647.0f64 as i32 , 2147483647 ) ;
115
- assert_eq :: < i32 > ( -2147483648.0f64 as i32 , -2147483648 ) ;
172
+ test_cast :: < f64 , i32 > ( 0.0 , 0 ) ;
173
+ test_cast :: < f64 , i32 > ( -0.0 , 0 ) ;
174
+ test_cast :: < f64 , i32 > ( /*0x1.199999999999ap+0*/ f64:: from_bits ( 0x3ff199999999999a ) , 1 ) ;
175
+ test_cast :: < f64 , i32 > ( /*-0x1.199999999999ap+0*/ f64:: from_bits ( 0xbff199999999999a ) , -1 ) ;
176
+ test_cast :: < f64 , i32 > ( 1.9 , 1 ) ;
177
+ test_cast :: < f64 , i32 > ( -1.9 , -1 ) ;
178
+ test_cast :: < f64 , i32 > ( 1e8 , 100_000_000 ) ;
179
+ test_cast :: < f64 , i32 > ( 2147483647.0 , 2147483647 ) ;
180
+ test_cast :: < f64 , i32 > ( -2147483648.0 , -2147483648 ) ;
116
181
// unrepresentable casts
117
182
assert_eq :: < i32 > ( 2147483648.0f64 as i32 , i32:: MAX ) ;
118
183
assert_eq :: < i32 > ( -2147483649.0f64 as i32 , i32:: MIN ) ;
119
184
120
185
// f64 -> i64
121
- assert_eq :: < i64 > ( 0.0f64 as i64 , 0 ) ;
122
- assert_eq :: < i64 > ( -0.0f64 as i64 , 0 ) ;
123
- assert_eq :: < i64 > ( /*0x0.0000000000001p-1022*/ f64:: from_bits ( 0x1 ) as i64 , 0 ) ;
124
- assert_eq :: < i64 > ( /*-0x0.0000000000001p-1022*/ f64:: from_bits ( 0x8000000000000001 ) as i64 , 0 ) ;
125
- assert_eq :: < i64 > ( /*0x1.199999999999ap+0*/ f64:: from_bits ( 0x3ff199999999999a ) as i64 , 1 ) ;
126
- assert_eq :: < i64 > ( /*-0x1.199999999999ap+0*/ f64:: from_bits ( 0xbff199999999999a ) as i64 , -1 ) ;
127
- assert_eq :: < i64 > ( 5.0f64 as i64 , 5 ) ;
128
- assert_eq :: < i64 > ( 5.9f64 as i64 , 5 ) ;
129
- assert_eq :: < i64 > ( -5.0f64 as i64 , -5 ) ;
130
- assert_eq :: < i64 > ( -5.9f64 as i64 , -5 ) ;
131
- assert_eq :: < i64 > ( 4294967296.0f64 as i64 , 4294967296 ) ;
132
- assert_eq :: < i64 > ( -4294967296.0f64 as i64 , -4294967296 ) ;
133
- assert_eq :: < i64 > ( 9223372036854774784.0f64 as i64 , 9223372036854774784 ) ;
134
- assert_eq :: < i64 > ( -9223372036854775808.0f64 as i64 , -9223372036854775808 ) ;
186
+ test_cast :: < f64 , i64 > ( 0.0 , 0 ) ;
187
+ test_cast :: < f64 , i64 > ( -0.0 , 0 ) ;
188
+ test_cast :: < f64 , i64 > ( /*0x0.0000000000001p-1022*/ f64:: from_bits ( 0x1 ) , 0 ) ;
189
+ test_cast :: < f64 , i64 > ( /*-0x0.0000000000001p-1022*/ f64:: from_bits ( 0x8000000000000001 ) , 0 ) ;
190
+ test_cast :: < f64 , i64 > ( /*0x1.199999999999ap+0*/ f64:: from_bits ( 0x3ff199999999999a ) , 1 ) ;
191
+ test_cast :: < f64 , i64 > ( /*-0x1.199999999999ap+0*/ f64:: from_bits ( 0xbff199999999999a ) , -1 ) ;
192
+ test_cast :: < f64 , i64 > ( 5.0 , 5 ) ;
193
+ test_cast :: < f64 , i64 > ( 5.9 , 5 ) ;
194
+ test_cast :: < f64 , i64 > ( -5.0 , -5 ) ;
195
+ test_cast :: < f64 , i64 > ( -5.9 , -5 ) ;
196
+ test_cast :: < f64 , i64 > ( 4294967296.0 , 4294967296 ) ;
197
+ test_cast :: < f64 , i64 > ( -4294967296.0 , -4294967296 ) ;
198
+ test_cast :: < f64 , i64 > ( 9223372036854774784.0 , 9223372036854774784 ) ;
199
+ test_cast :: < f64 , i64 > ( -9223372036854775808.0 , -9223372036854775808 ) ;
135
200
// unrepresentable casts
136
201
assert_eq :: < i64 > ( 9223372036854775808.0f64 as i64 , i64:: MAX ) ;
137
202
assert_eq :: < i64 > ( -9223372036854777856.0f64 as i64 , i64:: MIN ) ;
@@ -143,14 +208,14 @@ fn casts() {
143
208
assert_eq :: < i64 > ( ( -f64:: NAN ) as i64 , 0 ) ;
144
209
145
210
// f64 -> u64
146
- assert_eq :: < u64 > ( 0.0f64 as u64 , 0 ) ;
147
- assert_eq :: < u64 > ( -0.0f64 as u64 , 0 ) ;
148
- assert_eq :: < u64 > ( 5.0f64 as u64 , 5 ) ;
149
- assert_eq :: < u64 > ( -5.0f64 as u64 , 0 ) ;
150
- assert_eq :: < u64 > ( 1e16f64 as u64 , 10000000000000000 ) ;
151
- assert_eq :: < u64 > ( ( u64:: MAX -1023 ) as f64 as u64 , u64:: MAX ) ; // rounding loss
152
- assert_eq :: < u64 > ( ( u64:: MAX -1024 ) as f64 as u64 , u64:: MAX -2047 ) ; // rounding loss
153
- assert_eq :: < u64 > ( 9223372036854775808.0f64 as u64 , 9223372036854775808 ) ;
211
+ test_cast :: < f64 , u64 > ( 0.0 , 0 ) ;
212
+ test_cast :: < f64 , u64 > ( -0.0 , 0 ) ;
213
+ test_cast :: < f64 , u64 > ( 5.0 , 5 ) ;
214
+ test_cast :: < f64 , u64 > ( -5.0 , 0 ) ;
215
+ test_cast :: < f64 , u64 > ( 1e16 , 10000000000000000 ) ;
216
+ test_cast :: < f64 , u64 > ( ( u64:: MAX -1023 ) as f64 , u64:: MAX ) ; // rounding loss
217
+ test_cast :: < f64 , u64 > ( ( u64:: MAX -1024 ) as f64 , u64:: MAX -2047 ) ; // rounding loss
218
+ test_cast :: < f64 , u64 > ( 9223372036854775808.0 , 9223372036854775808 ) ;
154
219
// unrepresentable casts
155
220
assert_eq :: < u64 > ( 18446744073709551616.0f64 as u64 , u64:: MAX ) ;
156
221
assert_eq :: < u64 > ( f64:: MAX as u64 , u64:: MAX ) ;
0 commit comments