浮点-如果一个实数可以用双精度表示,我如何编写一个返回true的C++函数

floating point - How can I write a C++ function returning true if a real number is exactly representable with a double?

本文关键字:一个 何编写 返回 C++ 函数 true 实数 如果 双精度 浮点 表示      更新时间:2023-10-16

如果实数可以用双精度表示,我如何编写一个返回true的C++函数?

bool isRepresentable( const char* realNumber )
{
   bool answer = false;
   // what goes here?
   return answer;
}

简单测试:

assert( true==isRepresentable( "0.5" ) );
assert( false==isRepresentable( "0.1" ) );

将数字解析为a+N/(10^k)形式,其中a和N是整数,k是小数位数。

示例:12.0345->12+345/10^4,a=12,N=345,k=4

现在,10^k=(2*5)^k=2^k*5^k

当并且只有当你去掉分母中的5^k项时,你才能将你的数字表示为精确的二进制分数。

结果将检查(N mod 5^k)==0

神圣的作业,蝙蝠侠!:)

有趣的是,您不能简单地执行(atof|strtod|sscanf)->sprintf循环,然后检查是否返回了原始字符串。例如,在许多平台上,sprintf检测到"尽可能接近0.1"的双精度,并将其打印为0.1,即使0.1不能精确表示。

#include <stdio.h>
int main() {
    printf("%llx = %fn",0.1,0.1);
}

打印:3fb999999999999a=0.100000

在我的系统上。

真正的答案可能需要解析出二重,将其转换为精确的分数表示(0.1=1/10),然后确保atof转换乘以分母等于分子。

我想。

这是我的版本。sprintf将0.5转换为0.50000,必须删除末尾的零。

EDIT:必须重写才能正确处理以0结尾的无小数点数字(如12300)。

bool isRepresentable(const char*realNumber){bool answer=false;double dVar=atof(实数);字符检查[20];sprintf(check,"%f",dVar);//删除末尾的零-TODO:仅当字符串中有小数点时执行for(int i=strlen(check)-1;i>=0;i-){if(check[i]!='0')break;check[i]=0;}answer=(strcmp(realNumber,check)==0);返回答案;}

这应该可以做到:

bool isRepresentable(const char *realNumber)
{
    double value = strtod(realNumber, NULL);
    char test[20];
    sprintf(test, "%f", value);
    return strcmp(realNumber, test) == 0;
}

可能最好使用"安全"版本的sprintf来防止潜在的缓冲区溢出(在这种情况下可能吗?)

我会将字符串转换为其数字位表示形式(位数组或长),然后将字符串转换成双精度,看看它们是否匹配。

将字符串转换为范围大于双精度的浮点值。把它变成一个替身,看看它们是否匹配。