我想在特定计算机上找到尾数位数和单位四舍五入。我对这些是什么有所了解,不知道如何找到它们 - 虽然我知道它们可能因计算机而异。
我需要这个数字才能执行数值分析的某些方面,比如分析错误。
我目前的想法是,我可以编写一个小的c ++程序来缓慢增加一个数字,直到溢出发生,但我不确定使用什么类型的数字。
我是否在正确的轨道上?一个人如何计算这个呢?
答案 0 :(得分:5)
我认为您使用的任何语言都会指定浮点数的存储方式。我知道Java通过使用特定的IEEE标准(754,我认为)来做到这一点。
如果没有指定,我认为您可以通过添加0.5到1进行自己的检查,以查看实际数字是否发生变化。如果是,则添加0.25到1,将0.125添加到1,依此类推,直到数字不变,如:
float a = 1;
float b = 0.5;
int bits = 0;
while (a + b != a) {
bits = bits + 1;
b = b / 2;
}
如果你只有3个尾数位,那么1 + 1/16将等于1。
然后你已经用尽了尾数。
您可能实际上需要基数为2而不是1,因为IEEE754在开始时使用隐含的“1+”。
编辑:
看来上面描述的方法可能存在一些问题,因为它为一个明显具有4字节浮点数的系统提供了63位。
是否与中间结果有关(我怀疑它,因为具有显式强制转换[while (((float)(a + b) != (float)(a))
]的相同代码具有类似问题)或(更可能,我相信)单位值{{1}的可能性通过调整指数,可以用更接近小数a
的位表示,我还不知道。
目前,最好依赖我上面提到的语言信息,例如使用IEEE754(如果有这些信息)。
我会将有问题的代码留作警惕玩家的陷阱。也许有一个有更多浮点知识的人,然后我可以留下一个说明,解释为什么它行为奇怪(没有猜想,请: - )。
编辑2:
这段代码通过确保中间件存储在浮点数中来修复它。事实证明乔纳森莱弗勒是对的 - 这是中间结果。
b
}
此代码输出(24,24)以显示计算出的值与头文件中的值匹配。
虽然用C语言编写,但它应该适用于任何语言(特别是那些信息在标题中不可用或者在语言文档中指定的语言)。我只在C中测试过,因为Eclipse需要很长时间才能在我的Ubuntu盒子上启动: - )。
答案 1 :(得分:1)
对于C和扩展C ++,信息位于<float.h>
或<cfloat>
标题中。
对于C99,信息见标准的5.2.4.2.2节:
FLT_RADIX
FLT_MANT_DIG
FLT_DIG
FLT_EPSILON
FLT_MIN_EXP
FLT_MIN
FLT_MIN_10_EXP
FLT_MAX_EXP
FLT_MAX
FLT_MAX_10_EXP
同样对于大多数这些(无DBL_RADIX
或LDBL_RADIX
)的DBL和LDBL变体。该标准建议的值适用于IEEE 754(1999年的IEEE 754标准的旧版本;我相信,2008年发布了新版本)。
答案 2 :(得分:1)
您可能想要查看C ++库中的<limits>
:
#include <iostream>
#include <limits>
#include <typeinfo>
template <typename T>
void printDetailsFor() {
std::cout
<< "Printing details for " << typeid(T).name() << ":\n"
<< "\tradix: " << std::numeric_limits<T>::radix << "\n"
<< "\tradix digits: " << std::numeric_limits<T>::digits << "\n"
<< "\tepsilon: " << std::numeric_limits<T>::epsilon() << "\n"
<< std::endl;
}
int main() {
printDetailsFor<int>();
printDetailsFor<float>();
printDetailsFor<double>();
printDetailsFor<long double>();
return 0;
}
我认为您希望std::numeric_limits<T>::digits
应该比尾数位的数量多一个。我的机器打印出来:
Printing details for i:
radix: 2
radix digits: 31
epsilon: 0
Printing details for f:
radix: 2
radix digits: 24
epsilon: 1.19209e-07
Printing details for d:
radix: 2
radix digits: 53
epsilon: 2.22045e-16
Printing details for e:
radix: 2
radix digits: 64
epsilon: 1.0842e-19