[BUG] Decimal division loses precision when dividing by decimals with fractional parts
- 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
Assessment
This issue has not been assessed yet.