@@ -172,9 +172,9 @@ fn float_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
172
172
let args = PyFuncArgs :: new ( vec ! [ i. clone( ) , i2. clone( ) ] , vec ! [ ] ) ;
173
173
if objtype:: isinstance ( i2, & vm. ctx . float_type ( ) ) || objtype:: isinstance ( i2, & vm. ctx . int_type ( ) )
174
174
{
175
- let r1 = float_floordiv ( vm, args. clone ( ) ) ;
176
- let r2 = float_mod ( vm, args. clone ( ) ) ;
177
- Ok ( vm. ctx . new_tuple ( vec ! [ r1. unwrap ( ) , r2. unwrap ( ) ] ) )
175
+ let r1 = float_floordiv ( vm, args. clone ( ) ) ? ;
176
+ let r2 = float_mod ( vm, args. clone ( ) ) ? ;
177
+ Ok ( vm. ctx . new_tuple ( vec ! [ r1, r2] ) )
178
178
} else {
179
179
Err ( vm. new_type_error ( format ! (
180
180
"Cannot divmod power {} and {}" ,
@@ -190,18 +190,26 @@ fn float_floordiv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
190
190
args,
191
191
required = [ ( i, Some ( vm. ctx. float_type( ) ) ) , ( i2, None ) ]
192
192
) ;
193
- if objtype:: isinstance ( i2, & vm. ctx . float_type ( ) ) {
194
- Ok ( vm. ctx . new_float ( ( get_value ( i) / get_value ( i2) ) . floor ( ) ) )
195
- } else if objtype:: isinstance ( i2, & vm. ctx . int_type ( ) ) {
196
- Ok ( vm
197
- . ctx
198
- . new_float ( ( get_value ( i) / objint:: get_value ( i2) . to_f64 ( ) . unwrap ( ) ) . floor ( ) ) )
193
+
194
+ let v1 = get_value ( i) ;
195
+ let v2 = if objtype:: isinstance ( i2, & vm. ctx . float_type ) {
196
+ get_value ( i2)
197
+ } else if objtype:: isinstance ( i2, & vm. ctx . int_type ) {
198
+ objint:: get_value ( i2)
199
+ . to_f64 ( )
200
+ . ok_or_else ( || vm. new_overflow_error ( "int too large to convert to float" . to_string ( ) ) ) ?
199
201
} else {
200
- Err ( vm. new_type_error ( format ! (
202
+ return Err ( vm. new_type_error ( format ! (
201
203
"Cannot floordiv {} and {}" ,
202
204
i. borrow( ) ,
203
205
i2. borrow( )
204
- ) ) )
206
+ ) ) ) ;
207
+ } ;
208
+
209
+ if v2 != 0.0 {
210
+ Ok ( vm. ctx . new_float ( ( v1 / v2) . floor ( ) ) )
211
+ } else {
212
+ Err ( vm. new_zero_division_error ( "float floordiv by zero" . to_string ( ) ) )
205
213
}
206
214
}
207
215
@@ -229,14 +237,22 @@ fn float_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
229
237
args,
230
238
required = [ ( i, Some ( vm. ctx. float_type( ) ) ) , ( i2, None ) ]
231
239
) ;
232
- if objtype:: isinstance ( i2, & vm. ctx . float_type ( ) ) {
233
- Ok ( vm. ctx . new_float ( get_value ( i) % get_value ( i2) ) )
234
- } else if objtype:: isinstance ( i2, & vm. ctx . int_type ( ) ) {
235
- Ok ( vm
236
- . ctx
237
- . new_float ( get_value ( i) % objint:: get_value ( i2) . to_f64 ( ) . unwrap ( ) ) )
240
+
241
+ let v1 = get_value ( i) ;
242
+ let v2 = if objtype:: isinstance ( i2, & vm. ctx . float_type ) {
243
+ get_value ( i2)
244
+ } else if objtype:: isinstance ( i2, & vm. ctx . int_type ) {
245
+ objint:: get_value ( i2)
246
+ . to_f64 ( )
247
+ . ok_or_else ( || vm. new_overflow_error ( "int too large to convert to float" . to_string ( ) ) ) ?
248
+ } else {
249
+ return Err ( vm. new_type_error ( format ! ( "Cannot mod {} and {}" , i. borrow( ) , i2. borrow( ) ) ) ) ;
250
+ } ;
251
+
252
+ if v2 != 0.0 {
253
+ Ok ( vm. ctx . new_float ( v1 % v2) )
238
254
} else {
239
- Err ( vm. new_type_error ( format ! ( "Cannot mod {} and {}" , i . borrow ( ) , i2 . borrow ( ) ) ) )
255
+ Err ( vm. new_zero_division_error ( "float mod by zero" . to_string ( ) ) )
240
256
}
241
257
}
242
258
@@ -272,15 +288,22 @@ fn float_truediv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
272
288
args,
273
289
required = [ ( i, Some ( vm. ctx. float_type( ) ) ) , ( i2, None ) ]
274
290
) ;
291
+
275
292
let v1 = get_value ( i) ;
276
- if objtype:: isinstance ( i2, & vm. ctx . float_type ) {
277
- Ok ( vm . ctx . new_float ( v1 / get_value ( i2) ) )
293
+ let v2 = if objtype:: isinstance ( i2, & vm. ctx . float_type ) {
294
+ get_value ( i2)
278
295
} else if objtype:: isinstance ( i2, & vm. ctx . int_type ) {
279
- Ok ( vm
280
- . ctx
281
- . new_float ( v1 / objint:: get_value ( i2) . to_f64 ( ) . unwrap ( ) ) )
296
+ objint:: get_value ( i2)
297
+ . to_f64 ( )
298
+ . ok_or_else ( || vm. new_overflow_error ( "int too large to convert to float" . to_string ( ) ) ) ?
299
+ } else {
300
+ return Err ( vm. new_type_error ( format ! ( "Cannot divide {} and {}" , i. borrow( ) , i2. borrow( ) ) ) ) ;
301
+ } ;
302
+
303
+ if v2 != 0.0 {
304
+ Ok ( vm. ctx . new_float ( v1 / v2) )
282
305
} else {
283
- Err ( vm. new_type_error ( format ! ( "Cannot divide {} and {}" , i . borrow ( ) , i2 . borrow ( ) ) ) )
306
+ Err ( vm. new_zero_division_error ( "float division by zero" . to_string ( ) ) )
284
307
}
285
308
}
286
309
0 commit comments