Application Development and Automation 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: 
Read only

Showing Significant Digits

Former Member
0 Kudos
1,342

This probably has been answered before, but I have not been able to find it due to me not knowing the proper term for this.  My engineering users call it showing significant digits.  When they say I only want to see 4 significant digits they mean the decimal point will float depending on the value of the number so that only 4 digits show.  For example,  if a number has the value of less than 1 the there will be 4 decimal places (.9999) if between 1 and 9 then 3 decimal places (9.999), if between 10 and 99 then 2 decimal places (99.99)  etc...

1) What is this actually called,

2) Is there an existing function or static method that will do this?

3) (Bonus question) If not, how would you go about accomplishing this?

1 ACCEPTED SOLUTION
Read only

Former Member
0 Kudos
732

How about this?

FORM sig_digit  USINGp_value
                     p_digits
                     p_return.

  DATA:

intportion TYPE string,
numberval  TYPE string,
declength  TYPE i.

  numberval = round( val = p_value dec = p_digits ).

  SHIFT numberval LEFT DELETING LEADING '0'.

  SPLIT numberval AT '.' INTO intportion decportion.

  IF intportion IS INITIAL.

p_return = numberval.

  ELSE.

declength = p_digits - strlen( intportion ).
WRITE p_value TO p_return DECIMALS declength.

  ENDIF.

  shift p_return LEFT DELETING LEADING ' '.

ENDFORM.

13 REPLIES 13
Read only

Juwin
Active Contributor
0 Kudos
732

Hi Larry,

I don't think you need any special function module to achieve this. You should be able to achieve this, using character fields.

data:significant_digits(5),

     number      type p decimals 10,

     char_number type char20.

char_number = number = '0.99999999'.

condense char_number.

significant_digits = char_number(5).

write / significant_digits.

char_number = number = '9.99999999'.

condense char_number.

significant_digits = char_number(5).

write / significant_digits.

char_number = number = '99.9999999'.

condense char_number.

significant_digits = char_number(5).

write / significant_digits.

char_number = number = '999.999999'.

condense char_number.

significant_digits = char_number(5).

write / significant_digits.

char_number = number = '9999.99999'.

condense char_number.

significant_digits = char_number(5).

write / significant_digits.

Result:

0.999

9.999

99.99

999.9

9999.


Thanks,

Juwin

Read only

Former Member
0 Kudos
732

That would work, except rounding won't occur.  I guess I left that part out.  Also, 9999. should not have a decimal point and 0.999 should be .9999

Read only

Juwin
Active Contributor
0 Kudos
732
Also, 9999. should not have a decimal point and 0.999 should be .9999


This may require specific IF conditions - because this is only related to display not specific to calculation.

Rounding can be achieved by introducing another variable in the mix, with exact number of decimal points.

data:significant_digits(5),

      char_number    type string,

      number         type p decimals 10,

      rounded_number type p decimals 4.

significant_digits = char_number = rounded_number = number = '0.9998'.

write / significant_digits.

significant_digits = char_number = rounded_number = number = '9.9998'.

write / significant_digits.

significant_digits = char_number = rounded_number = number = '99.9998'.

write / significant_digits.

significant_digits = char_number = rounded_number = number = '999.9998'.

write / significant_digits.

significant_digits = char_number = rounded_number = number = '9999.9998'.

write / significant_digits.


Result:

0.999

9.999

99.99

999.9

9999.

Thanks,

Juwin

Read only

Former Member
0 Kudos
732

Well, this IS the problem I suppose.  I am looking for some thing more generic.

This is what I had come up with but was hoping for something that would work for any number of significant digits.

FORM sig_digit4 using

          num_var

          char_var                        type char5.

Check num_var < 10000.

if num_var > 999.95.

     write num_var to char_var decimals 0.

elseif num_var > 99.995.

     write num_var to char_var decimals 1.

elseif num_var > 9.9995.

     write num_var to char_var decimals 2.

elseif num_var > .99995.

     write num_var to char_var decimals 3.

else.

     write num_var to char_var decimals 4.

endif.

condense char_var.

ENDFORM.

I would need to write a separate subroutine for each different number of significant digits.

Read only

Juwin
Active Contributor
0 Kudos
732

You can use dynamic variable creation techniques to make this as generic as possible.

Thanks,

Juwin

Read only

Juwin
Active Contributor
0 Kudos
732

Can you try using this?

parameters:input  type p decimals 10 default '0.999999',

            digits type n default 4.

data:decportion type string,

      intportion type string,

      numberval  type string,

      declength  type i.

numberval = round( val = input dec = digits ).

split numberval at '.' into intportion decportion.

if numberval < 1. clear intportion. endif.

declength = digits - strlen( intportion ).

if declength < 0.

   write 'Err'. stop.

elseif declength = 0.

   numberval = intportion.

else.

   numberval = intportion && '.' && decportion(declength).

endif.

write numberval.

Thanks,

Juwin

Read only

Former Member
0 Kudos
732

Close, but I think it is not rounding properly.  The number of rounding decimals is going to depend of the value coming in.  Ex. 999.9 needs to round to 1 decimal while 99.99 needs to round to 2 decimals.

I was not aware of the "round" intrinsic?? function.  What is that?

This has potential, just need to think about it a bit more.

Read only

Juwin
Active Contributor
0 Kudos
732

Yep, didn't think too much about rounding. But, you get the idea now, right?

round function helps to round the value to any digits.

Thanks,

Juwin

Read only

Former Member
0 Kudos
732

I suppose this sort of answers my original question about a std SAP function or method to do this.  It just seems like there should something to do this.  I would think it is a common need for companies who do engineering work.

Read only

Former Member
0 Kudos
733

How about this?

FORM sig_digit  USINGp_value
                     p_digits
                     p_return.

  DATA:

intportion TYPE string,
numberval  TYPE string,
declength  TYPE i.

  numberval = round( val = p_value dec = p_digits ).

  SHIFT numberval LEFT DELETING LEADING '0'.

  SPLIT numberval AT '.' INTO intportion decportion.

  IF intportion IS INITIAL.

p_return = numberval.

  ELSE.

declength = p_digits - strlen( intportion ).
WRITE p_value TO p_return DECIMALS declength.

  ENDIF.

  shift p_return LEFT DELETING LEADING ' '.

ENDFORM.

Read only

0 Kudos
732

Here is what I ended up with.  Do you see any problems with it?

*&---------------------------------------------------------------------*

*&      Form  sig_digit

*&---------------------------------------------------------------------*

FORM sig_digit  USING

     f_value

     f_digits

     f_return.

  DATA:

     num_string  TYPE string,

     int_part    TYPE string,

     dec_part    TYPE string,

     declength   TYPE i.

  num_string = round( val = f_value dec = f_digits ).

  SHIFT num_string LEFT DELETING LEADING '0'.

  SPLIT num_string AT '.' INTO int_part dec_part.

  declength = f_digits - strlen( int_part ).

  WRITE f_value TO f_return DECIMALS declength.

  SHIFT f_return LEFT DELETING LEADING ' '.

  SHIFT f_return LEFT DELETING LEADING '0'.

ENDFORM.                    "sig_digit

Read only

Juwin
Active Contributor
0 Kudos
732

Yep, seems ok to me.

Read only

0 Kudos
732

Juwin,

Thanks for your help!