Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

A calculation precision issue with ABAP.

aicro_ai
Explorer

Hi guys,

I've met a question about division and multiply. Please see the following java codes.

double a = 154.8, b = 37, c = 144;

double d = b/c;

d = a * d;

The result of 'd' is 39.775

However, I've made a similar program in ABAP, see below.

data lv_decfloat34_1 type decfloat34.
data lv_decfloat34_2 type decfloat34.
data lv_decfloat34_3 type decfloat34.
data lv_decfloat34_4 type decfloat34.

lv_decfloat34_1 = '154.8'.
lv_decfloat34_2 = 37.
lv_decfloat34_3 = 144.

lv_decfloat34_4 = lv_decfloat34_2 / lv_decfloat34_3.
lv_decfloat34_4 = lv_decfloat34_1 * lv_decfloat34_4.
* result is 39,77499999999999999999999999999999

write: lv_decfloat34_4.

data lv_f_1 type f.
data lv_f_2 type f.
data lv_f_3 type f.
data lv_f_4 type f.

lv_f_1 = '154.8'.
lv_f_2 = 37.
lv_f_3 = 144.

lv_f_4 = lv_f_2 / lv_f_3.
lv_f_4 = lv_f_4 * lv_f_1.

* result is 3,9774999999999999E+01

write: lv_f_4.

data lv_p_1(16) type p DECIMALS 14.
data lv_p_2(16) type p DECIMALS 14.
data lv_p_3(16) type p DECIMALS 14.
data lv_p_4(16) type p DECIMALS 14.

lv_p_1 = '154.8'.
lv_p_2 = 37.
lv_p_3 = 144.

lv_p_4 = lv_p_2 / lv_p_3.
lv_p_4 = lv_p_4 * lv_p_1.

* result is 39,77499999999931

write: lv_p_4.

I've also made a similar experiment with C++. The result is the same as JAVA.

As customer is verifying result with Excel, which gives 39.775, not equal to our result. So we meet the problem. Can anybody help with this issue?

Thanks,

Aicro

1 ACCEPTED SOLUTION

horst_keller
Product and Topic Expert
Product and Topic Expert

Please read SAP's documentation about calculation type and conversion rules.

Please read SAP's documentation about ROUND.

5 REPLIES 5

former_member564522
Active Participant
0 Kudos

As per SAP predefined data elements, Decfloat16 can have 16 decimals and decfloat34 can have 34 decimals.

You can do the wrapper type P with 3 decimal to convert into desired decimal format.

below is code snippet you may use.

DATA lv_decfloat34_1 TYPE f.
DATA lv_decfloat34_2 TYPE f.
DATA lv_decfloat34_3 TYPE f.
DATA lv_decfloat34_4 TYPE f.
DATA lv_decfloat34_5 TYPE p DECIMALS 3.


lv_decfloat34_1 = '154.8'.lv_decfloat34_2 = 37.lv_decfloat34_3 = 144.
lv_decfloat34_4 = lv_decfloat34_2 / lv_decfloat34_3.lv_decfloat34_4 = lv_decfloat34_1 * lv_decfloat34_4.
lv_decfloat34_5 = lv_decfloat34_4

WRITE: lv_decfloat34_5.

0 Kudos

Hi Himanshu,

Thanks for your reply, but I do not want such conversion, as it's impossible to see to which decimal shall I reserve, ie in this case I have 3 decimal, but in other cases we need more. What JAVA and C++ does is so nature that it directly tells me the "right" result.

So I'm wondering, is there any way, including function modules, can have the same behavior like that of JAVA and C++.

Sandra_Rossi
Active Contributor
0 Kudos

If you read the ABAP documentation, you'll understand the reason (with 14 digits after the decimal point, 37/144 is stored as an unprecise value of 0.25694444444444, it can't store the fact that there's an endless sequence of "4", so because of the missing "4" from the 15th position, if you multiply by 37 you get 39.77499999999931).

But as I'm not expert with C++/java, I can't explain how these languages can get the right result because I thought that the "double" storage was the same logic as for ABAP type "F" (binary floating point on 8 bytes, with same mantissa and so on). Of course, here you are testing the decimal floating point types, which are different from "double".

horst_keller
Product and Topic Expert
Product and Topic Expert

Please read SAP's documentation about calculation type and conversion rules.

Please read SAP's documentation about ROUND.

matt
Active Contributor
0 Kudos

The output of your calculation is 39+(31/40) so is, exactly, 39.775.

What happens if you do it in a single step?

lv_decfloat34_4 = lv_decfloat34_1 * lv_decfloat34_2 / lv_decfloat34_3.<br>