0

Here is my code :

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    int n, i, num, m, k = 0;
    cout << "Enter a number :\n";
    cin >> num;
    n = log10(num);

    while (n > 0) {
        i = pow(10, n);
        m = num / i;
        k = k + pow(m, 3);
        num = num % i;
        --n;
        cout << m << endl;
        cout << num << endl;
    }
    k = k + pow(num, 3);
    return 0;
}

When I input 111 it gives me this

1
12
1
2

I am using codeblocks. I don't know what is wrong.

10
  • 1
    It sounds like you may need to learn how to use a debugger to step through your code. With a good debugger, you can execute your program line by line and see where it is deviating from what you expect. This is an essential tool if you are going to do any programming. Further reading: How to debug small programs Commented Nov 12, 2015 at 13:03
  • 1
    HINT: int != double Commented Nov 12, 2015 at 13:04
  • 3
    instead of saying C++ mod returns wrong answer, it might be more prudent to say mod doesn't return expected answer. Heavens forbid that you find a bug in mod after all these years. :D Commented Nov 12, 2015 at 13:18
  • Can you please elaborate your question? What is thos code supposed to do? What is it doing? Commented Nov 12, 2015 at 13:21
  • 1
    Modulus is NOT returning the wrong answer. Your output tells me that pow is returning the wrong answer, which is somewhat surprising but not impossible. pow(10,2) is returning 99.9999999999999 and assigning that to an int gives you 99. Commented Nov 12, 2015 at 13:30

2 Answers 2

3

Whenever I use pow expecting an integer result, I add .5 so I use (int)(pow(10,m)+.5) instead of letting the compiler automatically convert pow(10,m) to an int.

I have read many places telling me others have done exhaustive tests of some of the situations in which I add that .5 and found zero cases where it makes a difference. But accurately identifying the conditions in which it isn't needed can be quite hard. Using it when it isn't needed does no real harm.

If it makes a difference, it is a difference you want. If it doesn't make a difference, it had a tiny cost.

In the posted code, I would adjust every call to pow that way, not just the one I used as an example.

There is no equally easy fix for your use of log10, but it may be subject to the same problem. Since you expect a non integer answer and want that non integer answer truncated down to an integer, adding .5 would be very wrong. So you may need to find some more complicated work around for the fundamental problem of working with floating point. I'm not certain, but assuming 32-bit integers, I think adding 1e-10 to the result of log10 before converting to int is both never enough to change log10(10^n-1) into log10(10^n) but always enough to correct the error that might have done the reverse.

Sign up to request clarification or add additional context in comments.

Comments

0

pow does floating-point exponentiation.

Floating point functions and operations are inexact, you cannot ever rely on them to give you the exact value that they would appear to compute, unless you are an expert on the fine details of IEEE floating point representations and the guarantees given by your library functions.

(and furthermore, floating-point numbers might even be incapable of representing the integers you want exactly)

This is particularly problematic when you convert the result to an integer, because the result is truncated to zero: int x = 0.999999; sets x == 0, not x == 1. Even the tiniest error in the wrong direction completely spoils the result.

You could round to the nearest integer, but that has problems too; e.g. with sufficiently large numbers, your floating point numbers might not have enough precision to be near the result you want. Or if you do enough operations (or unstable operations) with the floating point numbers, the errors can accumulate to the point you get the wrong nearest integer.


If you want to do exact, integer arithmetic, then you should use functions that do so. e.g. write your own ipow function that computes integer exponentiation without any floating-point operations at all.

4 Comments

There are more advanced situations in which I'd agree with you. But at the level of this question, I think it is better to take the view that 64-bit double is plenty for operations on 32-bit integers, as long as you use a little extra care and thought on the conversions (plus a little extra care and thought to verify that you really are working with double and with 32-bit int).
In several questions at SO, I have seen (and sometimes helped with) use of double for log and pow of 64-bit integers. double is fundamentally not good enough for that job. But in specific uses, it still tends to end up better using double and compensating for the error, as compared to doing the job from scratch with a more exact representation.
While I agree with the general suggestions in this answer, saying "cannot ever rely on them" is taking it a bit too far. after a statement like x = 12.0 * 13.0; x is always exactly equal to 156; there are no rounding errors. True, you need to know a bit about IEEE (trivia like "floats can represent all integer numbers up to 16777216 without loss of precision" are good to know) but that doesn't mean you can't really use floating point unless you know all the ins and outs of the specs.
@MrLister: I don't doubt some things require much less expertise than others; the important point is that this is something you should only do when you know what you're doing, not, e.g., because you remember someone made a brief comment that some calculation was okay.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.