高分求教 如何用整型来表达浮点类型?(200)

  • 主题发起人 主题发起人 dinglj1760
  • 开始时间 开始时间
D

dinglj1760

Unregistered / Unconfirmed
GUEST, unregistred user!
问题是这样的,有一连串的坐标,类型为double,描述为x/y,x/y……现在的算法要求如下1.用整型来表达浮点类型2.表达后的整型需要字节压缩,达到占用的空间尽可能的小。下面举个例子。点1:00000008h: 80 9C 83 A0 CF 02 80 92 81 C5 E6 04点2:00000008h: 80 B4 86 A0 CF 02 80 88 81 C5 E6 04 点3:00000008h: 80 92 86 A0 CF 02 80 F8 FD C4 E6 04由这三个点顺序构成的线,存储的内容为:00000008h: 80 9C 83 A0 CF 02 80 92 81 C5 E6 04 80 98 03 C0 00000018h: 0A C0 22 C0 90 03 注意一个现象,第一个节点,用了12字节,也就是说,存储X坐标只用了6个字节。我们知道,int32需要4个字节,double类型需要8个字节,这6个字节是咋来的呢?就是整型压缩了。
 
你是让别人给你做一个将double压缩为int的算法?
 
志在讨论算法,如果有人做过这方面的研究,能谈谈最好了~
 
所谓的压缩,必须要有一定的数据量压缩才有效,数据量少的时候是无法压缩的。举例来说,winrar工具的压缩效果应该还可以,可是如果我新建一个文本文件,内容只有2个字节,为"AA",我对它进行压缩,压缩后的文件大小却是102字节。你的信息量太少,压缩过程中附带的压缩信息,会导致压缩后的内容远大于压缩前的内容。----------如果你数据比较多,可以先将数据写入一个流,然后调用zlib.TCompressionStream类进行压缩,类似案例:Procedure ZipFile(Source, OutFileName:String);//文件压缩var F:TCompressionStream
FSource,Fzip:TFileStream
i:integer;begin FSource:=TFileStream.Create(Source,fmOpenRead)
i:= FSource.Size
FZip:=TFileStream.Create(OutFileName,fmCreate)
F:=TCompressionStream.Create(clDefault,Fzip)
Try F.CopyFrom(FSource,0)
Finally F.Free
FSource.Free
End
Fzip.Write(i,sizeof(i))
Fzip.Free;end;procedure UnZipFIle(Source,OutFileName:String)
//文件解压var F:TDecompressionStream
FSource,FUnzip:TFileStream
Buffer: PChar
i:integer;begin if not FileExists(Source) Then Exit
DeleteTmpFile
FSource:=TFileStream.Create(Source,fmOpenRead)
FUnzip:=TFileStream.Create(OutFileName,fmCreate)
FSource.Position:=FSource.Size-Sizeof(integer)
FSource.Read(i,sizeof(i))
FSource.Position:=0
Try F:=TDecompressionStream.Create(FSource)
Finally End
GetMem(Buffer,i)
F.Read(Buffer^,i)
FUnzip.WriteBuffer(Buffer^,i)
FreeMem(Buffer)
F.Free
FSource.Free
FUnZip.Free;end;
 
看看Delphi里的 Real48 吧。另外,整型压缩是你自己定义的吧?
 
误解我的意思了。我打个比方说,一个double类型变量x=0.999;那么用二进制存储则占用8个字节(x86平台下),现在的问题是,人家用了6个字节就表示了这个变量。他的核心思想是针对字节的压缩,我抄一段原文过来:Point compression(点压缩)压缩或解压缩存储在二进制流中的点分两个步骤:转换到相对偏移方案并压缩为字节数组。解压缩与之相反,先从字节数组中解压缩,然后把值转为绝对坐标。每个过程都描述如下:Relatie-offset value calculation(相对偏移值的计算)转化坐标值为相对偏移的目的是使其在存储是占用尽可能少的字节。在一个存储相对偏移值的数组中,第一个值是点的绝对坐标(使用32位整数)后面的值都是相对前一个的偏移值.或者差值.因此,给定N个绝对坐标值,其绝对坐标计算如下:relative_value[0]=absolute_value[0]relative_value[1]=absolute_value[1]-absolute_value[0]...relative_value[N-2]=absolute_value[N-2]-absolute_value[N-3]relative_value[N-1]=absolute_value[N-1]-absolute_value[N-2]给定N个相对坐标值,其绝对坐标计算如下:absolute_value[0] = relative_value[0]absolute_value[1] = relative_value[0] + relative_value[1]...absolute_value[N-2] = relative_value[N-3] + relative_value[N-2]absolute_value[N-1] = relative_value[N-2] + relative_value[N-1]这种方法通常非常有效,因为一个特征的点往往都是紧密相临的压缩整数值相对偏移值一般比绝对坐标值要用更少的字节来表达,相对偏移值被压缩为一个字节序列。每个字节的高位作为控制位来表示结束标志,指示是否还有后续字节。例如:如果一个整数被压缩为三个字节,第一和第二个字节的高位被置位(指示还有一个后续的字节),第三个字节高位没有被置位(表示这个是整数的最后一个字节)。第一个字节的第二个位是符号标志。所以一个字节有一个控制位,一个符号位,和六个数据位。所有的后续字节都包括一个控制位和七个数据位。因为只有很少的数据位来表达一个整数,最多五个字节才能表达一个整数值,(这是最坏的情形,仅仅发生在整数值大于134,217,727)压缩字节的整数存储的形式=======================================================字节数目 位 值0 0 控制位(0 =最后一位,1=整数值延续到下个字节)0 1 符号位(0 =正整数,1=负整数)0 2~7 整数的其余六个位1-4 0 控制位(0 =最后一位,1=整数值延续到下个字节)1-4 2~7 整数的其余七个位整数值根据数据位的存储情况使用六个或七个位(在被压缩的值和0x3F或0x7F分别使用二进制OR操作)来存储到压缩的字节内。原始的值被向右移位(也就是将值划分为不同的部分)使用六个或七个位。如果新的,移位后的值不为零,那么在压缩字节内的控制位就被置位,并重复这个步骤,直到移位后的值为0。解压缩与此相似,是此过程的逆过程。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
733
import
I
后退
顶部