假设我们有一些序列作为输入。出于性能原因,我们可能希望将其转换为同类表示形式。为了将其转换为同类表示,我们正在尝试将其转换为相同类型。这里让我们只考虑输入中的2种类型-int64
和float64
(在我的简单代码中,我将使用numpy和python;这与问题无关紧要-人们可能只考虑64位整数和64位浮点数。
首先,我们可以尝试将所有内容强制转换为float64
。
因此,我们需要像这样的输入:
31 1.2 -1234
将转换为float64
。如果我们拥有所有int64
,则可以将其保留不变(“已经同质”),或者如果找到其他内容,我们将返回“不同质”。非常简单。
但这是问题所在。考虑一下修改后的输入:
31000000 1.2 -1234
想法很明确-我们需要检查“ caster”是否能够正确处理绝对值int64
:
format(np.float64(31000000), '.0f') # just convert to float64 and print
'31000000'
似乎根本不是问题。因此,让我们立即进行交易:
im = np.iinfo(np.int64).max # maximum of int64 type
format(np.float64(im), '.0f')
format(np.float64(im-100), '.0f')
'9223372036854775808'
'9223372036854775808'
现在它真的是不需要的-我们丢失了一些可能需要的信息。即我们要保留输入序列中提供的所有信息。
因此,我们的im
和im-100
值强制转换为相同的float64
表示形式。这样做的原因很明显-float64
在总共64位中只有53个有效位。这就是为什么其精度足以表示log10(2^53) ~= 15.95
,即大约所有16长度的int64
而没有任何信息丢失的原因。但是int64
类型最多可以包含19位数字。
因此,我们最终得到大约
[10^16; 10^19]
(更准确地说是[10^log10(53); int64.max]
)范围,其中每个int64
都可能表示信息丢失。
int64
和float64
。我现在看到几个选项:
int64
范围转换为float64
并“忘记”可能的信息丢失。> 10^16 int64
值”。float64
的阈值。并在决定投放时使用它。如果发现int64
高于此阈值-请勿进行转换(返回“不均匀”)。
log10(2^53)
舍入的。 "fint64"
。这是一个异乎寻常的决定,但我甚至还在考虑这样做的完整性。
int
和float
类型存储在一起时经常出现这种情况。其次-是float64
类型的结构。我不太了解为什么如果有效数字仅由其中的~308
个组成,而其他~16
本身就是一个噪声,那么为什么将需要~292
个数字的值范围。因此,我们可以使用float64
指数位之一来指示其float
或int
是否存储在此处。但是对于int64
,丢失1位肯定是缺点。原因会减小我们的整数范围两次。但是我们将有可能将int
与float
一起自由存储,而没有任何额外的开销。float64
和int64
失去了一定的范围。我们宁愿做的-不是减去1位而是添加一位,代表存储在后面64位中的int
或float
类型的标志。编辑
:因为这里出现问题,所以我需要尝试非常具体:所讨论的应用程序会执行以下操作-将int64
或float64
的序列转换为某种同构表示,如果可能的话,应无损。通过性能比较解决方案(例如,表示所需的总过量RAM)。就这些。这里没有考虑任何其他要求(因为我们应该在最小状态下考虑问题-而不是编写整个应用程序)。相应地,以均匀状态表示我们的数据的算法无损(我们确定我们不会丢失任何信息)适合我们的应用程序。
我已决定从问题中删除“ app”和“ user”一词-这也具有误导性。
答案 0 :(得分:1)
选择数据类型时有3个要求:
当然,硬件并没有提供很多类型可供选择;因此您需要选择下一个提供的最大类型。例如,如果要以8位精度存储范围从0到500的值;那么硬件将无法提供此类功能,您将需要使用16位整数或32位浮点数。
选择同构表示时,有3个要求:
例如,如果您具有从-10到+10000000000的整数,则需要一个不存在的35位整数类型,因此您将使用64位整数,并且如果需要从-2到... +2(31位精度),那么您需要一个不存在的33位浮点类型,因此您将使用64位浮点类型;从这两种原始类型的要求中,您将知道同构表示将需要符号标志,33位有效数字(带有隐含位)和1位指数。它不存在,因此您将使用64位浮点类型作为同类表示形式。
但是;如果您对原始数据类型的要求一无所知(并且只知道由于要求导致选择64位整数类型和64位浮点类型),那么您将必须承担“最坏的情况”。这导致需要具有符号标志,62位精度(加上一个隐含的1位)和8位指数的同构表示。当然,这种71位浮点类型不存在,因此您需要选择下一个最大的类型。
还请注意,有时没有硬件支持的“下一个最大类型”。发生这种情况时,您需要求助于“组合类型”-2个或更多原始类型的组合。可以包含不超过“大有理数”(以“分子/除数*(1 <<指数)”形式的3个大整数表示的数)的任何内容。
当然,如果原始类型(64位整数类型和64位浮点类型)是原始类型,并且您的同类表示形式需要使用“组合类型”;那么您的“ 出于性能原因,我们可能希望将其转换为同类表示形式”的假设可能是错误的(出于性能原因,您可能希望避免使用同类表示形式)。>
换句话说:
如果您对原始数据类型的要求一无所知,出于性能原因,您可能希望避免使用同质表示。
现在...
让我们将您的问题改写为“如何处理设计失败(选择不符合要求的错误类型)?”。只有一个答案,那就是避免设计失败。运行时检查(例如,如果转换为同类表示形式导致精度损失,则引发异常)除了将开发失败通知开发人员之外,没有其他用途。
答案 1 :(得分:1)
这实际上是非常基本的:使用64位浮点。浮点数 是一个近似值,您将失去许多整数的精度。但是除了“可能原先是不可或缺的”和“原始值是否偏离1.0以上”之外没有其他不确定性。
我知道一个非标准的浮点表示形式会更强大(可以在网上找到)。这可能(或可能不会)帮助覆盖整数。
拥有精确的int映射的唯一方法是减小int范围,并保证(例如)60位int是精确的,其余范围由浮点近似。浮点数也必须减小,要么是提到的指数范围,要么是精度(尾数)。