给定一个真实值,我们是否可以检查一个float
数据类型是否足以存储数字,或者double
是否需要 a?
我知道精度因架构而异。是否有任何 C/C++ 函数来确定正确的数据类型?
给定一个真实值,我们是否可以检查一个float
数据类型是否足以存储数字,或者double
是否需要 a?
我知道精度因架构而异。是否有任何 C/C++ 函数来确定正确的数据类型?
有关背景,请参阅每个计算机科学家应该了解的关于浮点运算的知识
不幸的是,我认为没有任何方法可以使决策自动化。
通常,当人们用浮点数而不是字符串表示数字时,其目的是使用数字进行算术运算。即使所有输入都以可接受的精度适合给定的浮点类型,您仍然必须考虑舍入误差和中间结果。
在实践中,大多数计算将使用 64 位类型以足够的精度获得可用结果。许多计算仅使用 32 位不会得到可用的结果。
在现代处理器中,总线和算术单元的宽度足以提供 32 位和 64 位浮点类似的性能。使用 32 位的主要动机是在存储非常大的数组时节省空间。
这导致了以下策略:
如果数组大到足以证明花费大量精力将其大小减半是合理的,请进行分析和实验以确定 32 位类型是否能提供足够好的结果,如果是,请使用它。否则,使用 64 位类型。
精度不是很依赖平台。虽然平台允许不同,但float
几乎是通用的IEEE标准单精度和双精度。double
单精度在小数点(小数点)之后分配 23 位“尾数”或二进制数字。由于点之前的位始终为 1,因此这相当于 24 位小数。除以 log2(10) = 3.3,浮点数可以得到7.2 个十进制数字的精度。
遵循相同的过程double
产生 15.9 位和long double
产生 19.2(对于使用 Intel 80 位格式的系统)。
尾数以外的位用于指数。指数位数决定了允许的数字范围。单到 ~ 10 ±38,双到 ~ 10 ±308。
至于您是否需要 7、16 或 19 位数字,或者是否完全适合有限精度表示,这确实超出了问题的范围。这取决于算法和应用程序。
我认为您的问题预设了一种在不损失精度的情况下为 C/C++(或任何其他程序)指定任何“实数”的方法。
假设您通过在代码中指定或通过用户输入来获得这个实数;检查浮点数或双精度数是否足以在不损失精度的情况下存储它的一种方法是仅计算有效位的数量并对照浮点数和双精度数的数据范围检查。
如果数字作为表达式(即1/7
或sqrt(2)
)给出,您还需要检测方法:
此外,还有一些数字,例如0.9
,float / double 在理论上不能“准确地”表示(至少在我们的二进制计算范式中不能) - 请参阅Jon Skeet 对此的出色回答。
最后,请参阅关于 float 与 double 的更多讨论。
您不能用浮点或双精度变量表示实数,而只能表示有理数的子集。
当您进行浮点计算时,您的 CPU 浮点单元将为您决定最佳近似值。
我可能错了,但我认为 float(4 字节)和 double(8 字节)浮点表示实际上是独立于 comp 架构指定的。
你不能简单地将它存储到一个float
和一个double
变量中然后比较这两个吗?这应该隐含地将float
back 转换为 double - 如果没有区别,float
就足够了吗?
float f = value;
double d = value;
if ((double)f == d)
{
// float is sufficient
}