cmath std :: pow函数分配给变量时给出错误的值? [英] cmath std::pow function giving wrong value when assigned to a variable?

查看:357
本文介绍了cmath std :: pow函数分配给变量时给出错误的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的方法跟踪特定数字从各组数字的分组中出现的次数。

The method below is keeping track of how many times specific numbers come up from groupings of various sets of numbers

void build_prob_distro(const std::vector<Foo>& num_sets, std::map<int, int>& prob_distro){
    int key;
    Foo cur_foo;

    for(unsigned int foo_num = 0; foo_num<num_sets.size(); foo_num++){
        cur_foo = num_sets.at(foo_num);
        key = 0;
        int val;
        for(int cur_foo_num=0; cur_foo_num<cur_foo.get_foo_length(); cur_foo_num++){
            std::cout << cur_foo.get_num_at(cur_foo_num)*std::pow(10, cur_foo.get_foo_length()-cur_foo_num-1) << std::endl;
            val = cur_foo.get_num_at(cur_foo_num)*std::pow(10, cur_foo.get_foo_length()-cur_foo_num-1);
            std::cout << val << std::endl;
            key = key + cur_foo.get_num_at(cur_foo_num)*std::pow(10, cur_foo.get_foo_length()-cur_foo_num-1);
        }

        prob_distro[key] += 1;
    }
}

我遇到的问题是当我使用std :: pow()方法来计算我的地图的关键值,任何超过100的关闭-1(即100变为99,103变为102等)。当我打印出使用std :: cout的计算结果是正确的,但是一旦我将该值赋给一个int变量,它得到-1的错误。我已经看了一遍又一遍的代码,没有看到任何立即出错。关于什么可能导致此问题和为什么的任何建议?

The problem I am running into is when I use the std::pow() method to calculate the key value for my map, anything over 100 is off by -1 (i.e. 100 becomes 99, 103 becomes 102, etc.). When I print out the calculation with std::cout the result is correct, but as soon as I assign the value to an int variable it get the -1 error. I have looked the code over and over and do not see anything immediately wrong with it. Any suggestions on what may cause this issue and why?

我不相信foo类对这个例子/问题太重要,但我会发布它只是-case它实际上是一些问题的原因。

I don't believe the foo class is too important to this example/issue, but I will post it just in-case it actually is the cause of some issue.

//Foo.h
#ifndef FOO_H
#define FOO_H

#include <string>
#include <vector>

class Foo
{
    public:
        Foo();
        Foo(const std::vector<int>& nums);
        int get_num_at(int pos) const;
        int get_foo_length() const;
        std::string to_string() const;
    private:
        std::vector<int> nums;

};

#endif // Foo_H


//Foo.cpp
#include "Foo.h"

#include <string>

Foo::Foo(const std::vector<int>& nums){
    for(int i=0; i<nums.size(); i++){
        this->nums.push_back(nums.at(i));
    }
}

Foo::Foo(){}


/*       SETTERS & GETTERS           */

int Foo::get_num_at(int pos) const{
    if(nums.size() != 0){
        return nums[pos];
    }

    return -1;
}

int Foo::get_foo_length() const{
    return nums.size();
}

/*       END SETTERS & GETTERS         */


std::string Foo::to_string() const{}

编辑:我知道一些会立即指向使用比Foo类更容易在向量中,但我有其他功能,我需要incorperated每个集合,所以这是最好的方式,我可以出来与我保持我的相关代码在一起,并允许它表示任何长度整数值我会感兴趣(即foo可以表示1,就像它可以表示10000)。

I know some will immediately point to using something easier than the Foo class in a vector, but I have other functionality that I need incorperated with each set, so this was the best way I could come up with to keep my related code together and allow it to represent any length integer value I would be interested in (i.e. foo can represent 1 just as easily as it can represent 10000).

推荐答案

您可能会出现舍入错误,

You're probably getting rounding errors,

所以,您可以尝试 std :: lround as:

so, you may try std::lround as:

key += cur_foo.get_num_at(cur_foo_num) * std::lround(std::pow(10, cur_foo.get_foo_length() - cur_foo_num - 1));

或写入您自己的 pow_int 使用 float

constexpr int pow_int(int x, unsigned int n)
{
    // x ** (2n + 1) == ((x * x) ** n) * x
    // x ** 2n == (x * x) ** n
    // x ** 0 == 1
    return (((n >> 1) == 0) ? 1 : pow_int(x * x, n >> 1)) * (((n & 1) == 0) ? 1 : x);
}

或(线性版本)

int pow_int(int x, unsigned int n)
{
    int res = 1;

    for (unsigned int i = 0; i != n; ++i) {
        res *= x;
    }
    return res;
}

这篇关于cmath std :: pow函数分配给变量时给出错误的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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