NVIDIA / NVIDIA/cudf

[BUG] Decimal division loses precision when dividing by decimals with fractional parts

Open
#17,448 5 comments 0 reactions 0 assignees View on GitHub
Python question
Dominant language
C++
Stars
9.8k
Forks
1.1k
Avg merge
3d 6m
Merged PRs (30d)
278

Description

**Describe the bug**
When performing division on Decimal64Dtype columns in cuDF, the result consistently loses the decimal fraction and becomes zero, depending on the precisions and scales of the input columns. This behavior is incorrect and does not match the expected results when calculated manually.

**Steps/Code to reproduce bug**
Here is a minimal code sample that reproduces the issue:

```
import cudf
from decimal import Decimal

# Test cases with varying precisions and scales
test_cases = [
{'a_dtype': cudf.Decimal64Dtype(2, 2), 'b_dtype': cudf.Decimal64Dtype(1, 0), 'description': 'Case 1: Dividing by an integer (scale=0)'},
{'a_dtype': cudf.Decimal64Dtype(2, 2), 'b_dtype': cudf.Decimal64Dtype(3, 2), 'description': 'Case 2: Dividing by a decimal-only real number (precision=scale)'},
{'a_dtype': cudf.Decimal64Dtype(3, 2), 'b_dtype': cudf.Decimal64Dtype(3, 2), 'description': 'Case 3: Dividing by a real number with both integer and decimal parts (precision > scale)'},
]

# Loop through the test cases
for case in test_cases:
print(case['description'])
df = cudf.DataFrame({'a': [Decimal('0.02')], 'b': [Decimal('2')]}).astype(
{
'a': case['a_dtype'],
'b': case['b_dtype'],
}
)
df['res'] = df['a'] / df['b']
print(df['res'], df['res'].dtype.precision, df['res'].dtype.scale)
```
Running this script produces the following output:
```
Case 1: Dividing by an integer (scale=0)
0 0.010000
Name: res, dtype: decimal64 6 6
Case 2: Dividing by a decimal-only real number (precision=scale)
0 0.000000
Name: res, dtype: decimal64 8 6
Case 3: Dividing by a real number with both integer and decimal parts (precision > scale)
0 0.000000
Name: res, dtype: decimal64 9 6
```

**Expected behavior**
The division results should retain the decimal fraction regardless of the precisions and scales of the input columns. Specifically:

- Case 1 (Dividing by an integer): The result is correct (0.01) as expected.
- Case 2 (Dividing by a decimal-only real number): The result is incorrect (0.00), but the expected value is 0.01.
- Case 3 (Dividing by a real number with both integer and decimal parts): The result is incorrect (0.00), but the expected value is 0.01.

For all cases, the division operation should preserve precision and produce consistent and accurate results based on manual calculations.

**Additional context**
This issue is consistently reproducible and appears to be related to how cuDF calculates the output precision and scale during division operations involving decimals. The incorrect handling leads to a loss of significant digits in the result.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.