如果真实数字可以用双精确表示,我怎么能写一个C ++函数返回true?
bool isRepresentable( const char* realNumber )
{
bool answer = false;
// what goes here?
return answer;
}
简单测试:
assert( true==isRepresentable( "0.5" ) );
assert( false==isRepresentable( "0.1" ) );
答案 0 :(得分:5)
神圣的作业,蝙蝠侠! :)
令人感兴趣的是,你不能简单地做一个(atof | strtod | sscanf) - > sprintf循环并检查是否有原始字符串。例如,许多平台上的sprintf检测到“尽可能接近0.1”并将其打印为0.1,即使0.1不能精确表示。
#include <stdio.h>
int main() {
printf("%llx = %f\n",0.1,0.1);
}
打印: 3fb999999999999a = 0.100000
在我的系统上。
真正的答案可能需要解析掉double以将其转换为精确的小数表示(0.1 = 1/10),然后确保分母的atof转换时间等于分子。
我想。
答案 1 :(得分:5)
将数字解析为a + N /(10 ^ k)形式,其中a和N是整数,k是你拥有的小数位数。
示例:12.0345 - &gt; 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
答案 2 :(得分:1)
这是我的版本。 sprintf将0.5转换为0.50000,最后必须删除零。
编辑:必须重写以处理没有小数点且正确结束的数字(如12300)。
bool isRepresentable( const char* realNumber ) { bool answer = false; double dVar = atof(realNumber); char check[20]; sprintf(check, "%f", dVar); // Remove zeros at end - TODO: Only do if decimal point in string for (int i = strlen(check) - 1; i >= 0; i--) { if (check[i] != '0') break; check[i] = 0; } answer = (strcmp(realNumber, check) == 0); return answer; }
答案 3 :(得分:0)
这应该可以解决问题:
bool isRepresentable(const char *realNumber)
{
double value = strtod(realNumber, NULL);
char test[20];
sprintf(test, "%f", value);
return strcmp(realNumber, test) == 0;
}
可能最好使用'安全'版本的sprintf来防止潜在的缓冲区溢出(在这种情况下甚至可能吗?)
答案 4 :(得分:0)
我将字符串转换为数字位表示(位数组或长数字),然后将字符串转换为double,看看它们是否匹配。
答案 5 :(得分:-2)
将字符串转换为范围大于double的浮点数。将其转换为双精度,看看它们是否匹配。