Как работает функция pow?

После компиляции следующей программы я получаю вывод «2346», но ожидал «2345».

#include<math.h>
#include<iostream.h>
int nr_cif(int a)
{
    int k=0;
    while(a!=0)
    {
        a = a/10;
        k++;
    }
    return k;
}

void Nr(int &a){
    int k = nr_cif(a);
    a = a % (int)pow(10,k-1);
}


int main()
{
    int a = 12345;
    Nr(a);
    cout<<a;
}

После отладки я заметил, что он дает ошибку после оценки: a = a % (int)pow(10,k-1). Почему здесь ломается?


person user3461699    schedule 29.03.2014    source источник
comment
Используйте <iostream>, а не <iostream.h>. <math.h> тоже будет немного лучше, чем <cmath>.   -  person chris    schedule 30.03.2014
comment
Отвечает ли это на ваш вопрос? Почему pow(5,2) становится равным 24?   -  person phuclv    schedule 07.06.2021


Ответы (2)


Не очень хорошая идея использовать pow для целочисленной математики. Я бы изменил код следующим образом:

void Nr(int &a)
{
    int ten_k = 1;
    while (ten_k < a) ten_k *= 10;
    a %= ten_k/10; // 10-to-the-(k-1)
}

В вашем коде нет ничего, что требовало бы количества десятичных цифр, только значение разряда. Так что сделайте значение места вашей переменной.

(Вы также можете использовать свой оригинальный цикл while, который лучше работает для отрицательных входных данных. Но вычислите и верните 10 в степени k вместо k).

Проблема с pow заключается в том, что он работает со значениями с плавающей запятой и дает очень близкие, но не точные результаты. Ошибки может быть достаточно, чтобы округленное значение (после приведения к int) было неверным. Вы можете обойти это, добавив 0,5 перед приведением... но в этом нет смысла, так как умножение в вашем цикле в любом случае быстрее, чем вызов pow.

person Ben Voigt    schedule 29.03.2014
comment
Спасибо за комментарий, но я не думаю, что он работает должным образом с этим кодом. Например, если мы возьмем a = 12. Он дважды пройдет через цикл while, поэтому ten_k в конечном итоге станет равным 100. Тогда «a» не изменит свое значение. Я хочу, чтобы он удалил свою первую цифру - person user3461699; 30.03.2014
comment
@ user3461699: Хорошо, ты прав. Используйте 1_ - person Ben Voigt; 30.03.2014

Я не силен в математике, но это работает: http://ideone.com/dFsODB

#include <iostream>
#include <cmath>

float mypow(float value, int pow)
{
    float temp = value;
    for (int i = 0; i < pow - 1; ++i)
        temp *= value;

    for (int i = 0; i > pow - 1; --i)
        temp /= value;

    return temp;
}


int main() 
{
    std::cout<<pow(10, -3)<<"\n";
    std::cout<<mypow(10, -3)<<"\n";
    return 0;
}
person Brandon    schedule 29.03.2014