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: 

Deleting trailing zeroes and decimal separator with String Templates

Former Member
0 Kudos

Can I use string templates to drop the trailing zeroes and, assuming there are no significant decimal numbers, the decimals separator?

As far as I know the way to do this in classic ABAP is either via SHIFT...DELETING or with the UNIT addition of the WRITE statement. I've found this related discussion on UNIT not having a string template equivalent and while I can see why that behaviour is too complex to add to string templates, I was hoping there was still a way to drop all non-significant trailing characters.

Can I do this with string templates or will I have to do it manually?

Example input > output:

231.0430   >  231.043
 21.1400   >   21.14
 78.050    >   78.05
158.4000   >  158.4
  7.00     >    7
1 ACCEPTED SOLUTION

horst_keller
Product and Topic Expert
Product and Topic Expert

Convert the numbers to decfloats and use them as embedded expressions in string templates. The default output format of decfloats has no decimal separators and no trailing zeros. You can use the CONV operator for that.

... |{ CONV decfloat34( '231.0430' ) }| ...
5 REPLIES 5

horst_keller
Product and Topic Expert
Product and Topic Expert

Convert the numbers to decfloats and use them as embedded expressions in string templates. The default output format of decfloats has no decimal separators and no trailing zeros. You can use the CONV operator for that.

... |{ CONV decfloat34( '231.0430' ) }| ...

Thanks for the quick response Horst. I ran a few tests already and while this does indeed seem to work as you describe, I noticed an inconsistency when storing the result of such a decfloat conversion in a string. Converting to decfloat and then either storing it as a decfloat or using it as that type directly in a WRITE statement or table expression works as expected. But storing a "CONV decfloat16( lv_input )" in a string type seems to still add trailing zeroes based on the type of lv_input.

I think that what's happening is that storing it as a string is reverting to standard output mechanisms and is ignoring the default output of the decfloat. But I'm not really sure why it would do that. I would expect the string to match what I'd print to the screen.

The following sample program displays the behaviour:

TYPES:
lty_dec2 TYPE p DECIMALS 2,
lty_dec6 TYPE p DECIMALS 6.
DATA:
lv_float    TYPE f,
lv_decfloat TYPE decfloat16,
lv_dec2     TYPE lty_dec2,
lv_string   TYPE string.

" Start from a float
lv_float = '3.10'.
WRITE 😕 |lv_float is set to '3.10' which outputs as: { lv_float }|.  " 3.1000000000000001
WRITE 😕 |As a decimal 2 that becomes: { CONV lty_dec2( lv_float ) }|. " 3.10
WRITE 😕 |And as a decimal 6: { CONV lty_dec6( lv_float ) }|. " 3.102400
WRITE 😕 |Written as a decfloat we get: { CONV decfloat16( lv_float ) }|. " 3.1
lv_string = CONV decfloat16( lv_float ).
WRITE 😕 |If we store the decfloat as a string we still get: { lv_string }|. " 3.1
lv_float = '3.10240'.
WRITE 😕 |Now add more significant digits, lv_float '3.10240' outputs as { lv_float }|. " 3.1023999999999998
WRITE 😕 |As a decfloat = { CONV decfloat16( lv_float ) }|. " 3.1024
lv_string = CONV decfloat16( lv_float ).
WRITE 😕 |And again when stored as a string: { lv_string }|. " 3.1024
WRITE :/.

WRITE 😕 |If we use a decfloat but want AT MOST 2 decimals: { CONV decfloat16( CONV lty_dec2( lv_float ) ) }|. " 3.1
lv_string = CONV decfloat16( CONV lty_dec2( lv_float ) ).
WRITE 😕 |But if we store THAT as a string: { lv_string }|. " 3.10
WRITE 😕 |Reconverting the string to decfloat: { CONV decfloat16( lv_string ) }|. " 3.1

lv_dec2 = lv_float.
lv_string = CONV decfloat16( lv_dec2 ).
WRITE 😕 |With an intermediary we still have a trailing zero: { lv_string }|. " 3.10

lv_string = CONV decfloat16( '4.50' ).
WRITE 😕 |Same when we convert a hard-coded value to decfloat and store it as a string: { lv_string }|. " 4.50

lv_decfloat = '4.50'.
WRITE 😕 |But it works when stored as a decfloat: { lv_decfloat }|. " 4.5

lv_string = lv_decfloat.
WRITE 😕 |That stored decfloat as a string: { lv_string }|. " 4.50

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

Also for storing in strings, you must then use the formatting for string templates and not the standard conversion (of course):

lv_string = |{ lv_decfloat }|.

instead of

lv_string = lv_decfloat.

0 Kudos

That does indeed work! To clarify my mistake: assigning non-string types to strings will use internal / standard conversion while a WRITE statement or, indeed, a string template will use external / output conversion?

horst_keller
Product and Topic Expert
Product and Topic Expert

One can say so.

There are conversion rules for assignments and special language constructs (WRITE TO, string templates) for formatting character strings.