如何通过 SnowSQL 或 Java 函数将十六进制 'F933F177' 转换为十进制 -114.036361?
How Can I Convert Hex 'F933F177' to Decimal -114.036361 via SnowSQL or a Java function?
我在 HEX 中存储了坐标,从网上搜索来看,它似乎使用了带符号的 2 的补码来处理负值。我对进行各种转换的位置有点迷茫,我认为路径应该是:
- 将十六进制转换为二进制。
- 将二进制转换为带符号的 2 的补码(有效地反转带符号的 2 的补码)。
- 转换为十进制
- 除以 1,000,000
我离这个过程还有多远?
我正在使用 Snowflake,因此我可以使用 SnowSQL 或 Java 联结来获得所需的结果。我不熟悉十六进制和带符号的 2 的补码。
如何对十六进制值 F933F177 进行逆向工程以获得十进制值 -114.036361?
包装来自 user16320675's comment using inline JAVA UDF 的代码:
create function transform_number(num varchar)
returns double
language java
handler='Test.transform_number'
target_path='@~/Test.jar'
as
$$
class Test {
public static double transform_number(String num) {
return Integer.parseUnsignedInt(num, 16) / 1_000_000.0;
}
}
$$;
函数调用:
SELECT transform_number('F933F177') AS result;
输出:
我喜欢 Lukasz Java 回答 - 很简单。
这里有一个纯 SQL 答案,如果您想要纯 SQL 可以使用它 - 它还有助于理解完成此转换的过程:
select 'F933F177' s
, to_number(s,'XXXXXXXX') n
, length(s) l
, pow(2, l/2*8) maxn
, iff(n>maxn/2-1, n-maxn, n) n2
, n2/1000000 n3
作为 SQL UDF:
create or replace function signed_two_compliment(s varchar)
returns float
as $$
select n3
from (
select to_number(s,'XXXXXXXX') n
, length(s) l
, pow(2, l/2*8) maxn
, iff(n>maxn/2-1, n-maxn, n) n2
, n2/1000000 n3
)
$$
;
我在 HEX 中存储了坐标,从网上搜索来看,它似乎使用了带符号的 2 的补码来处理负值。我对进行各种转换的位置有点迷茫,我认为路径应该是:
- 将十六进制转换为二进制。
- 将二进制转换为带符号的 2 的补码(有效地反转带符号的 2 的补码)。
- 转换为十进制
- 除以 1,000,000
我离这个过程还有多远?
我正在使用 Snowflake,因此我可以使用 SnowSQL 或 Java 联结来获得所需的结果。我不熟悉十六进制和带符号的 2 的补码。
如何对十六进制值 F933F177 进行逆向工程以获得十进制值 -114.036361?
包装来自 user16320675's comment using inline JAVA UDF 的代码:
create function transform_number(num varchar)
returns double
language java
handler='Test.transform_number'
target_path='@~/Test.jar'
as
$$
class Test {
public static double transform_number(String num) {
return Integer.parseUnsignedInt(num, 16) / 1_000_000.0;
}
}
$$;
函数调用:
SELECT transform_number('F933F177') AS result;
输出:
我喜欢 Lukasz Java 回答 - 很简单。
这里有一个纯 SQL 答案,如果您想要纯 SQL 可以使用它 - 它还有助于理解完成此转换的过程:
select 'F933F177' s
, to_number(s,'XXXXXXXX') n
, length(s) l
, pow(2, l/2*8) maxn
, iff(n>maxn/2-1, n-maxn, n) n2
, n2/1000000 n3
作为 SQL UDF:
create or replace function signed_two_compliment(s varchar)
returns float
as $$
select n3
from (
select to_number(s,'XXXXXXXX') n
, length(s) l
, pow(2, l/2*8) maxn
, iff(n>maxn/2-1, n-maxn, n) n2
, n2/1000000 n3
)
$$
;