Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

round to first non-zero digit

720975Sep 16 2009 — edited Sep 16 2009
I am looking for a way to round floating point values the first n'th non-zero digit to the right of the decimal point.

for example if n = 1 then

round 0.01111 to 0.01
round 0.001111 to 0.001
round 0.0001111 to 0.0001

If I use the round argument then I need a way to determine what the parameter should be for the 2nd argument.

This requires me knowing how many zeros are to the right of the decimal point and before the first non-zero digit.

I have developed the following function to determine this. It is based on the binary search algorithm and will iterate at most 8 times.
CREATE OR REPLACE FUNCTION NUMBER_OF_LEADING_ZEROS(P_VALUE BINARY_DOUBLE) RETURN NUMBER IS
	L_MIN_ZEROS NUMBER;
	L_MAX_ZEROS NUMBER;
	L_MID NUMBER;
	L_ABS_VALUE BINARY_DOUBLE;

BEGIN
	L_MIN_ZEROS := 0;
	L_MAX_ZEROS := 130;
	L_ABS_VALUE := ABS(P_VALUE);

	IF L_ABS_VALUE IS NULL THEN
		RETURN NULL;
	ELSIF L_ABS_VALUE = BINARY_DOUBLE_NAN Or L_ABS_VALUE < POWER(10, -L_MAX_ZEROS) Then
		RETURN L_MAX_ZEROS;
	ELSIF L_ABS_VALUE >= 0.1 Then
		RETURN 0;
	END IF;

	LOOP
		L_MID := TRUNC((L_MIN_ZEROS + L_MAX_ZEROS) / 2);
		IF L_ABS_VALUE < POWER(10, -L_MID) And L_ABS_VALUE >= POWER(10, -(L_MID + 1)) Then
			RETURN L_MID;
		ELSIF L_ABS_VALUE < POWER(10, -(L_MID + 1)) Then
			L_MIN_ZEROS := L_MID + 1;
		ELSE
			L_MAX_ZEROS := L_MID - 1;
		End If;
	END LOOP;

END;
If anyone can think of a more efficient way of doing this that would be great.
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Oct 14 2009
Added on Sep 16 2009
19 comments
1,878 views