具有C或D的浮点语义的整数类型

时间:2012-11-24 18:18:53

标签: c floating-point int d fixed-point

我正在寻找 C D 的现有实施方案,或实施,签名和/或无符号整数类型的建议浮点语义

也就是说,在执行算术时表现为浮点类型的整数类型:溢出产生无穷大 -infinity 签名的下溢)而不是环绕或具有未定义的行为,未定义的操作产生 NaN 等。

本质上是一个浮点版本,其中可呈现数字的分布均匀地落在数字线上,而不是在0附近聚合。

此外,所有操作都应确定性;任何给定的二进制补码32位架构应该为相同的计算产生完全相同的结果,无论其实现如何(而浮点可能,并且通常会产生稍微不同的结果)。

最后,表现是一个问题,让我担心潜在的“bignum”(任意精度)解决方案。

另请参阅:定点饱和算术

4 个答案:

答案 0 :(得分:3)

我不知道现有的任何实现。

但我想,实施它将是(在D中)的问题:

enum CheckedIntState : ubyte
{
    ok,
    overflow,
    underflow,
    nan,
}

struct CheckedInt(T)
    if (isIntegral!T)
{
    private T _value;
    private CheckedIntState _state;

    // Constructors, getters, conversion helper methods, etc.

    // And a bunch of operator overloads that check the
    // result on every operation and yield a CheckedInt!T
    // with an appropriate state.

    // You'll also want to overload opEquals and opCmp and
    // make them check the state of the operands so that
    // NaNs compare equal and so on.
}

答案 1 :(得分:2)

饱和算术除了未定义运算产生NaN的部分外,还能做你想要的算法。这将是有问题的,因为大多数饱和实现使用全数范围,因此没有留下值来为NaN保留。因此,你可能无法在饱和硬件指令的基础上轻松构建它,除非你有一个额外的“是这个值NaN”字段,这是相当浪费的。

假设您坚持NaN值的概念,所有边缘情况检测都可能需要在软件中进行。对于大多数整数运算,这非常简单,特别是如果您有更宽的类型可用(假设long long严格大于myType下的任何整数类型):

myType add(myType x, myType y) {
    if (x == positiveInfinity && y == negativeInfinity ||
        x == negativeInfinity && y == positiveInfinity)
        return notANumber;
    long long wideResult = x + y;
    if (wideResult >= positiveInfinity) return positiveInfinity;
    if (wideResult <= negativeInfinity) return negativeInfinity;
    return (myType)wideResult;
}

答案 2 :(得分:2)

一种解决方案可能是使用抽象数据类型实现多精度算术。 David Hanson的书籍 C接口和实现有一个MP算法的章节(接口和实现)。

使用缩放整数进行计算也是可能的。你可能能够使用他的任意精度算术,虽然我相信这个实现不会溢出。你可能会耗尽内存,但这是一个不同的问题。

在任何一种情况下,您可能需要调整代码以准确返回溢出等所需的内容。

Source code(麻省理工学院执照)

该页面还有一个从amazon.com购买该书的链接。

答案 3 :(得分:0)

在饱和算术中满足一半的要求,这些算法在例如ARM指令,MMX和SSE。

正如Stephen Canon所指出的那样,需要额外的元素来检查溢出/ NaN。一些指令集(Atmel至少)btw有一个粘滞标志来测试溢出(可用于区分inf和max_int)。也许“Q”+ 0可能标志着NaN。