1

我想知道一个数字是否在浮点表示中以一种方式表示,它是否将以相同的方式在具有更大尺寸的表示中表示。也就是说,如果一个数字具有特定的表示 a float,如果将其转换为 a ,它将具有相同的表示,然后float转换为 adouble时仍然相同long double

我想知道,因为我正在编写一个 BigInteger 实现,并且传入的任何浮点数都发送到一个接受 along double来转换它的函数。这引出了我的下一个问题。显然浮点并不总是有精确的表示,所以在我的 BigInteger 类中,当给定浮点数时我应该尝试表示什么。即使与传入的数字不同,尝试表示与给出的数字相同std::cout << std::fixed << someFloat;的数字是否合理。这是我能得到的最准确的表示吗?如果是这样的话, ...

提取该值的最佳方法是什么(以 10 的幂为底),目前我只是将它作为字符串抓取并将其传递给我的字符串构造函数。这会起作用,但我不禁觉得有更好的方法,但肯定会在除以我的基数时取余数,浮点数不准确。

最后,我想知道是否有一个浮点等价于uintmax_t, 那是一个类型名,它将始终是系统上最大的浮点类型,或者没有意义,因为long double它将始终是最大的(即使它与双)。

谢谢,T。

4

3 回答 3

9

如果“相同的表示”是指“内存中除了填充之外完全相同的二进制表示”,那么不是。双精度具有更多的指数和尾数位,并且具有不同的指数偏差。但我相信任何单精度值都可以用双精度精确表示(可能是非规范化值除外)。

当您说“浮点数并不总是具有精确表示”时,我不确定您的意思。当然,并非所有十进制浮点值都具有精确的二进制浮点值(反之亦然),但我不确定这是否是个问题。只要您的浮点输入没有小数部分,那么适当大的“BigInteger”格式就应该能够准确地表示它。

通过 base-10 表示的转换不是要走的路。理论上,您只需要一个长度约为 1024 的位数组,将其全部初始化为零,然后将尾数位移入指数值。但是在不了解您的实施的情况下,我无法提出更多建议!

于 2010-10-06T16:18:04.970 回答
2

double包括float;的所有值 long double包括 的所有值double。因此,您不会因转换为long double. 但是,您会丢失有关原始类型的相关信息(见下文)。

为了遵循常见的 C++ 语义,浮点值到整数的转换应该截断该值,而不是舍入。

主要问题是不精确的大值。您可以使用该frexp函数查找浮点值的以 2 为底的指数。您可以使用它std::numeric_limits<T>::digits来检查它是否在可以精确表示的整数范围内。

我个人的设计选择是断言 fp 值在可以精确表示的范围内,即对任何实际参数范围的限制。

要正确地做到这一点,您需要重载floatdouble参数,因为可以表示的范围完全取决于实际参数的类型。

当您的 fp 值在允许范围内时,您可以使用floorandfmod提取任何您想要的数字系统中的数字。

于 2010-10-06T18:27:37.853 回答
0

是的,从 IEEE 浮点数到双精度数到扩展,您会看到从较小格式到较大格式的位,例如

单身的
S EEEEEEEE 嗯嗯嗯......
双倍的
S EEEEEEEEEEEE 嗯……

6.5单
0 10000001 101000...
6.5双
0 10000000001 101000...
13单
0 10000010 101000...
13双
0 10000000010 101000...

您将留下的尾数对齐,然后添加零。

指数是右对齐的,将符号扩展到 msbit 旁边,然后复制 msbit。

例如 -2 的指数。取-2减去1,即-3。二进制补码中的 -3 是 0xFD 或 0b11111101,但格式中的指数位是 0b01111101,msbit 反转。对于双 -2 指数 -2-1 = -3。或 0b1111...1101 变为 0b0111...1101,msbit 反转。(指数位 = twos_complement(exponent-1) 与 msbit 反转)。

正如我们在上面看到的 3 3-1 = 2 0b000...010 的指数反转高位 0b100...010

所以是的,您可以从单精度中获取位并将它们复制到双精度数中的正确位置。我没有方便的扩展浮点参考,但很确定它的工作方式相同。

于 2010-10-08T01:10:01.243 回答