如何检测以10为底的十进制数是否可以精确表示为2 [英] How to detect if a base 10 decimal can be represented exactly in base 2

查看:46
本文介绍了如何检测以10为底的十进制数是否可以精确表示为2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为数字库测试的一部分,我需要选择可以精确地表示为2的10个基数的十进制数.如何在C ++中检测如果可以精确地以2的基数表示的10个十进制数?

As part of a numerical library test I need to choose base 10 decimal numbers that can be represented exactly in base 2. How do you detect in C++ if a base 10 decimal number can be represented exactly in base 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;
}

我使用以下值测试了此功能:-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.

I tested this function with the following values: -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. It returns true for -1.0/4.0, 0.0, 7.0/8.0, 1.0, 99.005 which is correct.

还有更好的主意吗?

推荐答案

我认为您要查找的是一个具有小数部分的数字,该部分是2的负幂序列的总和(aka:1等于a2的幂).我相信这应该始终能够准确地用IEEE浮点数/双精度数来表示.

I think what you are looking for is a number which has a fractional portion which is the sum of a sequence of negative powers of 2 (aka: 1 over a power of 2). I believe this should always be able to be represented exactly in IEEE floats/doubles.

例如:

0.375 =(1/4 + 1/8),应具有准确的表示形式.

0.375 = (1/4 + 1/8) which should have an exact representation.

如果要生成这些.您可以尝试执行以下操作:

If you want to generate these. You could try do something like this:

#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;
}

我相信您的函数的接口已损坏.如果您有这样会更好:

I believe your function has a broken interface. It would be better if you had this:

bool canBeRepresentedExactly(int numerator, int denominator);

因为并非所有分数都具有精确的表示形式,但是当您将其推为两倍时,您选择了二进制形式的表示形式……这违背了测试的目的.

because not all fractions have exact representations, but the moment you shove it into a double, you've chosen a representation in binary... defeating the purpose of the test.

这篇关于如何检测以10为底的十进制数是否可以精确表示为2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆