我想知道一个数字是否在浮点表示中以单向表示,它是否会在具有更大尺寸的表示中以相同的方式表示。
也就是说,如果某个数字的特定表示形式为float
,那么如果将float
强制转换为double
,它是否具有相同的表示形式,然后在转换为{long double
时仍然相同{1}}。
我想知道因为我正在写一个BigInteger实现和传入的任何浮点数我发送给一个接受long double
转换它的函数。这引出了我的下一个问题。显然浮点并不总是具有精确的表示,所以在我的BigInteger类中,当给定浮点数时我应该尝试表示什么。尝试表示std::cout << std::fixed << someFloat;
给出的相同数字是否合理,即使这与传入的数字不同。这是否是我能得到的最准确的表示?如果是这样,......
提取该值的最佳方法是什么(以10的幂为基础),此时我只是将其作为字符串抓取并将其传递给我的字符串构造函数。这样可行,但我不禁觉得这是一个更好的方法,但当我用基数划分时,肯定会拿下余数,这对浮点数来说并不准确。
最后,我想知道是否存在等价于uintmax_t
的浮点数,这是一个始终是系统中最大浮点类型的类型名称,或者没有意义,因为long double
将会永远是最大的(即使它与双倍相同)。
谢谢,T。
答案 0 :(得分:9)
如果通过“相同表示”表示“除了填充之外,内存中的二进制表示完全相同”,则表示没有。双精度具有指数和尾数的更多位,并且还具有不同的指数偏差。但我相信任何单精度值都可以用双精度表示(除了可能的非规范化值)。
当你说“浮点并不总是有确切的表示”时,我不确定你的意思。当然,并非所有十进制浮点值都具有精确的二进制浮点值(反之亦然),但我不确定这是一个问题。只要您的浮点输入没有小数部分,那么适当大的“BigInteger”格式应该能够准确地表示它。
通过基础10表示的转换不是要走的路。理论上,您只需要一个长度为~1024的位数组,将其全部初始化为零,然后将尾数位移入指数值。但是,如果不了解您的实施情况,我可以提出更多建议!
答案 1 :(得分:2)
double
包含float
的所有值; long double
包含double
的所有值。因此,您不会通过转换为long double
而丢失任何有价值的信息。但是,您丢失了有关原始类型的信息,这是相关的(见下文)。
为了遵循常见的C ++语义,将浮点值转换为整数应截断该值,而不是舍入。
主要问题是大的值不准确。您可以使用frexp
函数查找浮点值的基数2指数。您可以使用std::numeric_limits<T>::digits
检查是否在可以准确表示的整数范围内。
我的个人设计选择是断言fp值在可以精确表示的范围内,即对任何实际参数范围的限制。
要做到这一点,你需要使用float
和double
参数进行重载,因为可以精确表示的范围取决于实际参数的类型。
当你的fp值在允许的范围内时,你可以使用floor
和fmod
来提取你想要的任何数字系统中的数字。
答案 2 :(得分:0)
是的,从IEEE float到double再扩展,您将看到从较小格式到较大格式的位,例如
single S EEEEEEEE MMMMMMM..... double S EEEEEEEEEEEE MMMMM.... 6.5 single 0 10000001 101000... 6.5 double 0 10000000001 101000... 13 single 0 10000010 101000... 13 double 0 10000000010 101000...
您将左对齐尾数,然后添加零。
指数是右对齐,符号扩展到msbit旁边然后复制msbit。
例如指数为-2。取-2减1,即-3。二进制补码中的-3为0xFD或0b11111101,但格式中的指数位为0b01111101,msbit为反转。并且对于双a -2指数-2-1 = -3。或0b1111 ... 1101,变为0b0111 ... 1101,msbit反转。 (指数位= twos_complement(exponent-1),msbit反转)。
如上所述,指数为3 3-1 = 2 0b000 ... 010反转高位0b100 ... 010
所以是的,您可以从单精度中获取位并将它们复制到双精度数中的适当位置。我没有一个扩展的浮动参考方便,但很确定它的工作方式相同。