跳转至

IDL 中正浮点数的六十进制编码

原文链接: https://www.nv5geospatialsoftware.com/Learn/Blogs/Blog-Details/base-60-encoding-of-positive-floating-point-numbers-in-idl

18492 给本文评分:

3.5

IDL 中正浮点数的六十进制编码

匿名 2017年2月2日,星期四

这里是一个使用有限符号集高效表示数字的示例。我使用一组 60 个符号(或字符)将浮点数编码为任意选定长度的字符串。字符串越长,数字的精度可能就越高。

以下是一个表示示例,为了保持示例简短,这里仅限于正数。

IDL> a=[14.33, 3.1415, 12345]

IDL> a

14.330000       3.1415000       12345.000

IDL> base60(a)

FotV*

FdiDx

HdzS*

IDL> base60(a, precision=8)

FotV**aO

FdiDx*^c

HdzS****

IDL> base60(base60(a)) - a

-4.5533356836102712e-006 -4.6258149324351905e-006    -0.016666666666424135

IDL> base60(base60(a, precision=8)) - a

-9.2104102122902987e-012 -4.6052051061451493e-013 -7.7159711509011686e-008

在这个例子中,可以看到 5 位数的表示不如 8 位数的表示接近原始数字。

base60 函数的代码示例如下。

;

; 将数值类型转换为六十进制表示

; 将六十进制字符串转换为浮点表示

; PRECISION 仅用于确定编码时使用多少个符号,

; 在解码时被忽略。

function Base60, input, precision=precision

compile_opt idl2,logical_predicate

; 仅为编码设置默认精度为 5 位数字

if ~keyword_set(precision) then precision = 5

; 六十进制的符号集

symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*'

base = strlen(symbols)

; 从符号到值的快速转换

lut = bytarr(256)

lut[byte(symbols)] = bindgen(base)

if isa(input, /string) then begin

; 将 base60 字符串转换为浮点数

; 先找到指数

scale = replicate(double(base),n_elements(input)) ^ $

(lut[byte(strmid(input,0,1))] - base/2)

res = dblarr(n_elements(input))

for i=max(strlen(input))-1,1,-1 do begin

dig = lut[byte(strmid(input,i,1))]

res += dig

res /= base

endfor

res *= scale

endif else begin

; 将浮点数转换为 base60 字符串

; 首先编码指数(比例)

ex = intarr(n_elements(input))

arr = input

dbase = double(base)

repeat begin

dec = fix(arr ge 1)

ex += dec

arr *= dbase ^ (-dec)

inc = fix(arr lt 1/dbase)

ex -= inc

arr *= dbase ^ inc

endrep until array_equal(arr lt 1 and arr ge 1/dbase,1b)

if max(ex) ge base/2 || min(ex) lt -base/2 then begin

message, '数字超出了可表示的范围'

endif

bsym = byte(symbols)

res = string(bsym[reform(ex+base/2,1,n_elements(ex))])

for i=1,precision-1 do begin

arr *= base

fl = floor(arr)

arr -= fl

res += string(bsym[reform(fl,1,n_elements(fl))])

endfor

endelse

return, res

end

何时使用 IDL 任务?在异构计算环境中作为数据分析关键工具的 IDL First Valley 阴影检测