使用 MODULO DIVISION 方法将十进制数转换为十六进制数
Converting Decimal to Hexadecimal number using MODULO DIVISION method
我正在转换十进制数
42541956123769884636017138956568135808
转十六进制数
20014860486000000000000000008880
我的转换值为20014860486000000000000000019980
我的 Postgresql 转换函数是
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;
我正在使用模余数法。所以我用 16
取给定数字的模数,并将给定的十进制数除以 16
以进行连续的十六进制数转换。在第一次迭代中取模时,我得到
0
as remainder as last digit of hexadecimal number 20014860486000000000000000008880
and next dividend is 2658872257735617789751071184785508488
在第二次迭代中取模 2658872257735617789751071184785508488
得到
8
as remainder second from last digit of hexadecimal number 20014860486000000000000000008880
and next dividend is 166179516108476111859441949049094281
在第三次迭代中取模 166179516108476111859441949049094281
得到
9
as remainder but 8
is the exact hexadecimal digit to come in
third from last digit of hexadecimal number 20014860486000000000000000008880
如果上述分红值是166179516108476111859441949049094280
而不是 166179516108476111859441949049094281
那么我将得到余数 8
。我怎样才能得到准确的十六进制值 20014860486000000000000000008880
而不是 20014860486000000000000000019980
如果你这样说,你会得到 floating-point 除法,这会导致精度损失。
ip_number = trunc(ip_number/16);
改为这样说
ip_number = div(ip_number,16);
编辑后的完整源代码:
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';
我正在转换十进制数
42541956123769884636017138956568135808
转十六进制数
20014860486000000000000000008880
我的转换值为20014860486000000000000000019980
我的 Postgresql 转换函数是
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;
我正在使用模余数法。所以我用 16
取给定数字的模数,并将给定的十进制数除以 16
以进行连续的十六进制数转换。在第一次迭代中取模时,我得到
0
as remainder as last digit of hexadecimal number20014860486000000000000000008880
and next dividend is
2658872257735617789751071184785508488
在第二次迭代中取模 2658872257735617789751071184785508488
得到
8
as remainder second from last digit of hexadecimal number20014860486000000000000000008880
and next dividend is
166179516108476111859441949049094281
在第三次迭代中取模 166179516108476111859441949049094281
得到
9
as remainder but8
is the exact hexadecimal digit to come in third from last digit of hexadecimal number20014860486000000000000000008880
如果上述分红值是166179516108476111859441949049094280
而不是 166179516108476111859441949049094281
那么我将得到余数 8
。我怎样才能得到准确的十六进制值 20014860486000000000000000008880
而不是 20014860486000000000000000019980
如果你这样说,你会得到 floating-point 除法,这会导致精度损失。
ip_number = trunc(ip_number/16);
改为这样说
ip_number = div(ip_number,16);
编辑后的完整源代码:
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';