在C 中实现长双重

Implementation of long double in c++

本文关键字:实现      更新时间:2023-10-16

最近我正在进行一些有关C 类型的研究,并且对long double有几个问题。例如,我有一些数字long double x = -48.12e4,那么我应该将0.12转换为十六进制或垃圾箱的准确性(我更喜欢使用十六进制,更轻松地阅读)。在实施方案中,我额外有1位,我不知道它的角色 -

//scheme 
1bit    15bit   1bit   63bit 
sign    e        1       m

例如,让我们以我之前写过的数字。

1)translate decimal to hex 
-48.12 = -3.1E (are 2 digits after decimal enough?)
2)normalization 
0011.0001 1110  * 10^0 =  001.1 0001 1110 * 10^1
3)calculation of "e"
16 383 + 4 + 1 = 16 388 = 4004(hex) = 0100 0000 0000 0100
4)collecting everything together
1    0100 0000 0000 0100   1    1000 1111 0000 0..0
sign|        e           |bit|      mantisa 
What is that 1 bit for?
5)reverse order
0..000  0011 1100 0110  0000 0010  1010 0000 

我做了一切正确吗?

来自cppreference(强调矿山):

长双 - 扩展精度浮点类型。不是 必须映射到IEEE-754规定的类型。通常是80位x87 x86和x86-64架构上的浮点类型。

您假设long double的特定布局绝不是由标准保证的,但可能会因编译器而异,并且取决于目标体系结构。

您遇到的问题是您正在执行十进制数学。这对于人类来说是合乎逻辑的,但计算机的工作原理是合乎逻辑的。

特别是,-48.12e4被指定为符号,Mantissa,指数,这也是long double的C 实现的工作方式,但指数的隐式基础也有所不同。e4表示10的功率,但long double使用base-2(或base-16或其他二进制基础)。

结果是编译器不能仅仅转换指数。10^3是大约 2^10,但对于float,沿long double,甚至还不够近。

因此,适当的解决方案要困难得多。也许最简单的解决方案是计算long double(4812)long double(1e2),然后乘以这些解决方案。这样,您只需要实现整数转换为long double,而将10的功率转换为long double

将10向long double的小正势转换也很容易,重复使用整数代码。对于大型的积极力量,请使用平方。对于10的负功率,请使用pow(10,n)=1.0/pow(10,-n)

的事实

了解真正的编译器是如何做到的(这更有效),请查看strtod()的开源实现。