cancel
Showing results for 
Search instead for 
Did you mean: 

How to find first non-zero decimal place?

alexsr700
Participant
0 Kudos
760

Hello everyone,

I would like to display numbers with a defined amount of decimal places.

Let's take 0.001

local numbervar Decimals :=2
toText(Value, Decimals)

This would result in "0.00".

So, if the resulting number where to only contain zeros, I would like to increase the amount of decimals to the first non-zero.

Does anybody know a formula that counts the amount of decimal zeros?

Only the ones before the first non-zero of course, i.e. 0.0010002 should return 2 and not 5.

Thank you very much 🙂

Alex

Accepted Solutions (1)

Accepted Solutions (1)

alexsr700
Participant
0 Kudos

Okay, so I played a lot with your answer and just could not get around defining the number of decimals for the conversion to text. Plus, the toText() function is limited to 10 decimals.

On Tek Tips I got an answer that I was able to adjust to my issue.

This should work (optionally limit to e.g. 99 iterations to prevent overflow or add an Ìf Number<>0)):

local numbervar Number:=10.00000123;
local numbervar Decimals:=0;
local numbervar End_Bit:=0;

While End_Bit=0 Do
    (
    If (Number - TRUNCATE(Number)) * (10^Decimals) >= 1 Then
        End_Bit:=1
    Else
        Decimals:=Decimals+1
    );
Decimals<br>
alexsr700
Participant
0 Kudos

So there are three outcomes.

number - trunc(number
= 0 -> no decimals
= 0 < x < 1 -> leading zero
>= 1 -> first non zero decimal

If ((Number - TRUNCATE(Number)) * (10^Decimals) >= 1) OR (Number- Truncate(Number)=0) Then
                    End_Bit:=1
                Else
                    Decimals:=Decimals+1
                )
        );
Decimals 

if it is possible to check if the number following the first non-zero decimal is itself a zero?

Answers (3)

Answers (3)

ido_millet
Active Contributor
0 Kudos

Here is the combined solution, including automatic detection of the decimal separator character:

local numbervar myNumber := 0.0010002;
local stringvar Full_Decimals_As_String := Split(ToText(myNumber, 8), ToText(0.1)[2])[2];
local stringvar Partial_Decimals_As_String := ToText(Val(Full_Decimals_As_String),0,"");
Len(Full_Decimals_As_String) - Len(Partial_Decimals_As_String);
alexsr700
Participant
0 Kudos

Hello ido.millet

unfortunately, the problem with the amount of decimals remains.

I tried using this, but it fails

https://userapps.support.sap.com/sap/support/knowledge/en/1998005

alexsr700
Participant
0 Kudos

I am using your code without changes.

EDIT:

I found the problem. It is because my system is set to decimal comma right now. When I switch to decimal point, it works. So I need a routine to check if decimal comma or decimal point is used.

I think this is the approach you meant, right? Will test with a few more use cases to test system compatibilities.

local numbervar myNumber := 0.0010002;
local stringvar Full_Decimals_As_String := Split(ToText(myNumber, 8), ToText(0.1)[2])[2];
local stringvar Partial_Decimals_As_String := ToText(Val(Full_Decimals_As_String),0,"");
Len(Full_Decimals_As_String) - Len(Partial_Decimals_As_String);
ido_millet
Active Contributor
0 Kudos

Here's one option:

local numbervar myNumber := 0.0010002;
local stringvar Full_Decimals_As_String := Split(ToText(myNumber, 8), ".")[2];
local stringvar Partial_Decimals_As_String := ToText(Val(Full_Decimals_As_String),0,"");
Len(Full_Decimals_As_String) - Len(Partial_Decimals_As_String);
alexsr700
Participant
0 Kudos

Thank you @ ido.millet 🙂

Three quick follow up questions:

1. Is it necessary to define the length of the number? The number lengths will vary and the number of decimals could even be 0 (i.e. an integer).

2. You defined the decimal point. Is it possible to use decimal point "and" decimal comma as possible separators (some users use comma). Maybe something more elegant than

If toText(myNumber) like "*.*" Then
   local stringvar Full_Decimals_As_String := Split(ToText(myNumber, 8), ".")[2]
Else
   local stringvar Full_Decimals_As_String := Split(ToText(myNumber, 8), ",")[2];

3. What does the `[2]` do? Is it not an expression for an array? But it is not used again in the formula?

ido_millet
Active Contributor
0 Kudos

The 8 argument is for the number of decimals, not for the length of the number.

To detect the decimal separator character, You can use something like:

ToText(0.1)[2]
alexsr700
Participant
0 Kudos

Well, yes, it is the number of decimals but that is deriver from the length of the number. The number of decimals is an unknown, so cannot be defined beforehand.

I don't understand the

ToText(0.1)[2]

Does it convert the number to a text with decimal point or what does it do?

alexsr700
Participant
0 Kudos

P.S.:

I get an error that the length of the index must be between 1 and length of the array.

If I change array to [1] I get the result of "9", which is not the amount of zeros.

Split(ToText(myNumber, 8), ".")[2];
ido_millet
Active Contributor
0 Kudos

I can't make it fail, so please provide the full details (all the text in your formula, including the input number you are testing with).

ido_millet
Active Contributor
0 Kudos

See my suggestion above to identify the decimal separator character:

ToText(0.1)[2]