(float_ty, float_val, decimal_ty, decimal_ctx,
max_precision)
| 2373 | |
| 2374 | |
| 2375 | def check_cast_float_to_decimal(float_ty, float_val, decimal_ty, decimal_ctx, |
| 2376 | max_precision): |
| 2377 | # Use the Python decimal module to build the expected result |
| 2378 | # using the right precision |
| 2379 | decimal_ctx.prec = decimal_ty.precision |
| 2380 | decimal_ctx.rounding = decimal.ROUND_HALF_EVEN |
| 2381 | expected = decimal_ctx.create_decimal_from_float(float_val) |
| 2382 | # Round `expected` to `scale` digits after the decimal point |
| 2383 | expected = expected.quantize(decimal.Decimal(1).scaleb(-decimal_ty.scale)) |
| 2384 | s = pa.scalar(float_val, type=float_ty) |
| 2385 | actual = pc.cast(s, decimal_ty).as_py() |
| 2386 | if actual != expected: |
| 2387 | # Allow the last digit to vary. The tolerance is higher for |
| 2388 | # very high precisions as rounding errors can accumulate in |
| 2389 | # the iterative algorithm (GH-35576). |
| 2390 | diff_digits = abs(actual - expected) * 10**decimal_ty.scale |
| 2391 | limit = 2 if decimal_ty.precision < max_precision - 2 else 4 |
| 2392 | assert diff_digits <= limit, ( |
| 2393 | f"float_val = {float_val!r}, precision={decimal_ty.precision}, " |
| 2394 | f"expected = {expected!r}, actual = {actual!r}, " |
| 2395 | f"diff_digits = {diff_digits!r}") |
| 2396 | |
| 2397 | |
| 2398 | # Cannot test float32 as case generators above assume float64 |
no test coverage detected