Converting Decimal to Hexadecimal Number Using Modulo Division Method

Converting Decimal to Hexadecimal Number Using Modulo Division Method

I am converting Decimal number

42541956123769884636017138956568135808

to hexadecimal number

20014860486000000000000000008880

My converted value is 20014860486000000000000000019980

My Postgresql function for conversion is

CREATE OR REPLACE FUNCTION ipv6_dec_hex(ip_number numeric)
  RETURNS character varying AS
$BODY$
DECLARE

    ip  int :=null;
    ip1 character varying := '';
    ip2 character varying;

BEGIN
        while(ip_number != 0)
        LOOP
            ip = trunc(mod(ip_number,16));
            ip_number = trunc(ip_number/16);
            ip1:=ip1||to_hex(ip);
            raise notice 'ip is %',ip;
            raise notice 'ip_number is %',ip_number;

        END LOOP;
        ip2:=reverse(ip1);

        return ip2;
END;
   $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

I am using modulo-remainder method. so I am taking modulus for the given number with 16 and divide given decimal number by 16 for consecutive hexadecimal number conversions. While taking modulus in first iteration I am getting

0 as remainder as last digit of hexadecimal number 20014860486000000000000000008880

and next dividend is 2658872257735617789751071184785508488

In second iteration taking modulus of 2658872257735617789751071184785508488 getting

8 as remainder second from last digit of hexadecimal number 20014860486000000000000000008880

and next dividend is 166179516108476111859441949049094281

In third iteration taking modulus of 166179516108476111859441949049094281 getting

9 as remainder but 8 is the exact hexadecimal digit to come in third from last digit of hexadecimal number 20014860486000000000000000008880

If the above dividend value is 166179516108476111859441949049094280 instead of 166179516108476111859441949049094281 then i will get the remainder value as 8 . How could i get the exact hexadecimal value 20014860486000000000000000008880 instead of 20014860486000000000000000019980

1

1 Answer

If you say this you'll get floating-point division, and that will give a loss of precision.

ip_number = trunc(ip_number/16);

Say this instead

ip_number = div(ip_number,16);

docs here

full source after edit:

CREATE OR REPLACE FUNCTION ipv6_dec_hex(ip_number numeric)
  RETURNS character varying AS
$BODY$
DECLARE

    ip  int :=null;
    ip1 character varying := '';
    ip2 character varying;

BEGIN
        while(ip_number != 0)
        LOOP
            ip = mod(ip_number,16);
            ip_number = div(ip_number,16);
            ip1:=ip1||to_hex(ip);
            raise notice 'ip is %',ip;
            raise notice 'ip_number is %',ip_number;

        END LOOP;
        ip2:=reverse(ip1);

        return ip2;
END;
   $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

select ipv6_dec_hex(42541956123769884636017138956568135808)
   ='20014860486000000000000000008880';

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

James H. Sterling
Author

James H. Sterling

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.