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

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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