1

可能有人熟悉将一组有效浮点数强制为基于乘法运算的组的技巧和技术吗?

也就是说,给定任意两个浮点数(“double a,b”),什么样的操作序列,包括乘法,会变成另一个有效的浮点数?(有效的浮点数是任何 1 归一化的数字,不包括 NaN、非正规数和 -0.0)。

把这个粗略的代码:

double a = drand();
while ( forever ) 
{
    double b = drand();
    a = GROUP_OPERATION(a,b); 
    //invariant - a is a valid floating point number
}    

由于 NaN,仅靠自身相乘是行不通的。理想情况下,这将是一种直线方法(避免“如果高于 X,则除以 Y”公式)。

如果这不适用于所有有效的浮点数,是否有一个子集可供此类操作使用?

(我正在寻找的模型类似于 C 中的整数乘法 - 无论两个整数相乘,你总是得到一个整数)。

4

5 回答 5

3

(我正在寻找的模型类似于 C 中的整数乘法 - 无论两个整数相乘,你总是得到一个整数)。

整数模 2^N 不形成一个组 - 哪个整数乘以 2 得到 1?要使整数成为乘法组,您必须对素数进行模数。(例如 Z mod 7, 2*4 = 1,所以 2 和 4 互为倒数)

对于浮点值,简单的乘法或加法饱和到 +/- 无穷大,并且不存在与无穷大相反的值,因此该集合不是封闭的,或者它缺乏可逆性。

另一方面,如果您想要类似于以 2 的幂为模的整数乘法,那么乘法就可以了——有些元素没有逆,所以它不是一个群,但它是封闭的——你总是会得到一个浮点值。对于真正组的浮点子集,请参阅 lakshmanaraj 的答案。

于 2009-02-28T21:33:27.213 回答
1

由于舍入错误,浮点数永远不会形成您所说的意义上的组。考虑一下数值分析类中的任何那些可怕的例子,比如 0.1 不能用二进制精确表示。

但是从这个意义上说,即使是计算整数也不会形成一个群,因为它们在乘法下也不是封闭的。(证明:计算 的结果while true do x = x*x。在某些时候,你会超过字的大小,用完 BIGNUM 的资源,或者其他什么。)

@UnderAchievementAward 的更新:

-- 在这里添加,所以我可以得到格式,不像评论

由于我从浮点(而不是“实”数)开始,我不能避免任何 0.1 表示问题吗?“x = x*x”问题是为什么需要额外的操作来将结果保持在有效范围内。

好的,但是你会遇到这样一种情况,即存在一些x,y st 0 ≤ x,y < max其中xy < 0。或者同样不直观的东西。

关键是您当然可以定义一组看起来像有限表示集上的组的操作,但是如果您尝试将其用作正常的算术运算,它会做一些奇怪的事情。

于 2009-02-27T07:33:13.437 回答
1

浮点数由位支持。这意味着您可以在浮点值的整数表示上使用整数算术,并且您将获得一个组。

不确定这是否非常有用。

/* You have to find the integer type whose size correspond to your double */
typedef double float_t;
typedef long long int_t;

float_t group_operation(float_t a, float_t b)
{
  int_t *ia, *ib, c;
  assert(sizeof(float_t) == sizeof(int_t));
  ia = &a;
  ib = &b;
  c = *ia * *ib;
  return (float_t)c;
}
于 2009-02-27T07:38:02.050 回答
0

如果组运算是乘法,那么如果 n 是最高位,则 r1=1/power(2,n-1) 是您可以运算的最小十进制数,并且集合 [r1,2 * r1,4 * r1,8 * r1...1] union [-r1, -2 * r1, -4 * r1,....-1] union [0] 将是您所期望的组。对于整数 [1,0,-1] 是组。

如果组操作可以是其他任何东西,则形成 n 组有效组,

A(r)=cos(2*Pi*r/n) 从 r=0 到 n-1

和组操作是

COS(COSINV(A1)+COSINV(A2))

不知道你要不要这个......

或者如果您希望将 INFINITY 设置为有效组,则

简单的答案:GROUP OPERATION = AVG(A1,A2) = (A1+A2)/2

或者某些函数存在 F,它具有 FINV 作为它的逆,然后是 FINV(F(A1)+F(A2)/2) F 的示例是对数、逆、平方等。

 double a = drand();
while ( forever ) 
{
    double b = drand();
    a = (a+b)/2
  //invariant - a is a valid floating point number
}

或者,如果您希望将 DIGITAL 格式的 INFINITY 集作为有效组,则令 L 为最低浮点数,H 为最高浮点数

那么组操作 = AVG(A1,A2, L, H) = (A1+A2+L+H)/4

对于所有正数,此操作将始终在 L 和 H 内。

出于实际目的,您可以将 L 作为最低十进制数的四倍,将 H 作为(最高十进制数/4)。

double l = (0.0000000000000000000000000//1) * 4
double h = (0xFFFFFFFFFFFFFFFFFFFFFF///F) / 4
double a = abs(drand()) / 4;

while ( forever ) 
{
    double b = abs(drand()) / 4;
    a = (a+b+l+h)/4
//invariant - a is a valid floating point number
}

这具有所有正浮点数 / 4 的子集。

于 2009-02-27T07:57:54.220 回答
-1

整数在乘法下不会形成一个群——0没有逆。

于 2009-03-01T02:49:49.513 回答