作为数值库测试的一部分,我需要选择可以在基数2中精确表示的10位十进制数.如何在C++中检测基数为10的十进制数是否可以在基数2中精确表示?
我的第一个猜测如下:
bool canBeRepresentedInBase2(const double &pNumberInBase10)
{
//check if a number in base 10 can be represented exactly in base 2
//reference: http://en.wikipedia.org/wiki/Binary_numeral_system
bool funcResult = false;
int nbOfDoublings = 16*3;
double doubledNumber = pNumberInBase10;
for (int i = 0; i < nbOfDoublings ; i++)
{
doubledNumber = 2*doubledNumber;
double intPart;
double fracPart = modf(doubledNumber/2, &intPart);
if (fracPart == 0) //number can be represented exactly in base 2
{
funcResult = true;
break;
}
}
return funcResult;
}
Run Code Online (Sandbox Code Playgroud)
我用以下值测试了这个函数:-1.0/4.0,0.0,0.1,0.2,0.205,1.0/3.0,7.0/8.0,1.0,256.0/255.0,1.02,99.005.对于-1.0/4.0,0.0,7.0/8.0,1.0,99.005,它返回true,这是正确的.
有更好的想法吗?
我认为你所寻找的是一个数字,它有一个小数部分,它是一系列2的负幂(也就是:2的2次幂)的总和.我相信这应该始终能够在IEEE浮点数/双打中完全表示.
例如:
0.375 =(1/4 + 1/8)应具有精确的表示.
如果你想生成这些.你可以尝试做这样的事情:
#include <iostream>
#include <cstdlib>
int main() {
srand(time(0));
double value = 0.0;
for(int i = 1; i < 256; i *= 2) {
// doesn't matter, some random probability of including this
// fraction in our sequence..
if((rand() % 3) == 0) {
value += (1.0 / static_cast<double>(i));
}
}
std::cout << value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
编辑:我相信你的功能有一个破碎的界面.如果你有这个会更好:
bool canBeRepresentedExactly(int numerator, int denominator);
Run Code Online (Sandbox Code Playgroud)
因为并非所有分数都具有精确的表示形式,但是当你把它推到一个双精度表中时,你已经选择了二进制表示法......从而破坏了测试的目的.
归档时间: |
|
查看次数: |
2695 次 |
最近记录: |