(float_ty, float_val, decimal_ty, decimal_ctx,
max_precision)
| 2227 | |
| 2228 | |
| 2229 | def check_cast_float_to_decimal(float_ty, float_val, decimal_ty, decimal_ctx, |
| 2230 | max_precision): |
| 2231 | # Use the Python decimal module to build the expected result |
| 2232 | # using the right precision |
| 2233 | decimal_ctx.prec = decimal_ty.precision |
| 2234 | decimal_ctx.rounding = decimal.ROUND_HALF_EVEN |
| 2235 | expected = decimal_ctx.create_decimal_from_float(float_val) |
| 2236 | # Round `expected` to `scale` digits after the decimal point |
| 2237 | expected = expected.quantize(decimal.Decimal(1).scaleb(-decimal_ty.scale)) |
| 2238 | s = pa.scalar(float_val, type=float_ty) |
| 2239 | actual = pc.cast(s, decimal_ty).as_py() |
| 2240 | if actual != expected: |
| 2241 | # Allow the last digit to vary. The tolerance is higher for |
| 2242 | # very high precisions as rounding errors can accumulate in |
| 2243 | # the iterative algorithm (GH-35576). |
| 2244 | diff_digits = abs(actual - expected) * 10**decimal_ty.scale |
| 2245 | limit = 2 if decimal_ty.precision < max_precision - 2 else 4 |
| 2246 | assert diff_digits <= limit, ( |
| 2247 | f"float_val = {float_val!r}, precision={decimal_ty.precision}, " |
| 2248 | f"expected = {expected!r}, actual = {actual!r}, " |
| 2249 | f"diff_digits = {diff_digits!r}") |
| 2250 | |
| 2251 | |
| 2252 | # Cannot test float32 as case generators above assume float64 |
no test coverage detected