1

I'm trying to deal with money (probably the wrong way as far as best practices but I thought it would work.. its simple, multiply everything by 100 and then use ints)

    import java.util.Scanner;

public class PFiveFifteen {

public static void main(String[] args) 
{   
    Scanner in =new Scanner(System.in);

    int i = 0;
    double principalIn;
    int duration=0;
    double interestRate=0;
    int thisYear = 0;
    int iInterestRate = 0;
    int iPrincipalIn = 0;

    System.out.println("Please input initial amount: ");
    principalIn = in.nextDouble(); 
    iPrincipalIn= (int) principalIn *100;
    //System.out.println(principalIn*100);

    System.out.println("Please input interest rate as a decimal: ");
    interestRate = in.nextDouble()*100; 
    iInterestRate = (int) interestRate;
    //System.out.println(interestRate*100);

    System.out.println("Please input duration of investment in years: ");
    duration = in.nextInt(); 
    //System.out.println(duration);

    while(duration > i ) {

        if ( i == 0) {
            //System.out.println("Preloop value" + (iInterestRate));
            thisYear = (iPrincipalIn * iInterestRate)+ iPrincipalIn;
            //System.out.println("Postloop value" + (iPrincipalIn));
            i++;
            System.out.println("The initial value is " + thisYear);
            System.out.println("Year # one one: " +i);
            }
        else

    thisYear = (thisYear*iInterestRate) + thisYear;
    i++;
    System.out.println(thisYear/10000);
    System.out.println("year # " +i);
    }

But I'm somehow getting negative numbers back in console

    Please input initial amount: 

10000

Please input interest rate as a decimal: 100.00

Please input duration of investment in years: 10

The initial value is 1411065408

Year # one one: 1 141106

year # 2 -119738

year # 3 -72104

year # 4 4904

year # 5 84261

year # 6 21917

year # 7 154073

year # 8 -145664

year # 9 63722

year # 10

What in the world is going on here? I could get if there where whacky decimals or soemthing ( even though I cast it all to ints) but what the dickens is taking all positive inputs to below zero??

dosmastr
  • 7
  • 5
  • http://stackoverflow.com/questions/24223440/biginteger-returning-negative-numbers its something to do with this isn't it? – dosmastr Apr 13 '16 at 04:30
  • You are overflowing the integer, the max value in Java is 2,147,483,647. Once it overflows, I think it just goes negative or something, I know its weird... You could use class BigInteger if you needed really big numbers. – djs Apr 13 '16 at 04:30
  • Even smalls values will still break it: Please input initial amount: 10000 Please input interest rate as a decimal: .05 Please input duration of investment in years: 10 The initial value is 6000000 Year # one one: 1 600 year # 2 3600 year # 3 21600 year # 4 129600 year # 5 -81393 year # 6 -58864 year # 7 76312 year # 8 28378 year # 9 170272 year # 10 – dosmastr Apr 13 '16 at 04:30
  • i tried formatting that and the comment won't do it like I did above. – dosmastr Apr 13 '16 at 04:32
  • i wouldn't think the math im doing, compound interest of 5% on 10000 over 10 loops would exceed the max allowed by int. somewhere its continuing to multiply the interest by 100 but i don't see where that would be. – dosmastr Apr 13 '16 at 04:37
  • the funny part is i thought this would be EASIER.... FML – dosmastr Apr 13 '16 at 04:45
  • Why don't you use BigDecimals, as you tagged? They are just as accurate and robust as ints (since they **are** integers with an extra scale), they do not overflow and they are scaled already, so no need to rescale them all the time. There is no good reason to use ints here. Ints are just more work. – Rudy Velthuis Apr 13 '16 at 22:49

2 Answers2

1

Your idea of representing money amounts as integers is an OK one, but you have to be very careful of the scaling, especially when you multiply (or divide). Say you start with a principal of $10, which you represent as 1000. Then you enter an interest rate of 0.06 (I assume that the user is entering an actual rate and not a percentage, so 0.06 means 6%). You then represent that as 6.

So if your principal is P, the int you're using to represent it is P*100. And if your interest rate is I, the int you're using to represent it is I*100.

So now you want to compute P*I. Since you're representing everything as 100 times the actual value, you presumably want to get an int whose value is P*I*100. But when you multiply the two ints you have, P*100 and I*100, the result is P*I*10000 -- a factor of 100 too high. That's because you multiplied the scale factors together along with the values. I can see that you did output thisYear / 10000, but you didn't change thisYear. So as you keep going through the loop, you will get values that are a factor of 10000 too high, and 1000000 too high, and so on, and eventually you will overflow. (I wish things really did work that way, but unfortunately I can't talk my bank into using your algorithm.)

To adjust, you'll need to divide this result by 100. (I'd add 50 to it first, so that when you divide by 100 the result will be rounded.)

ajb
  • 31,309
  • 3
  • 58
  • 84
  • 1
    I don't quite understand why so many people prefer to use ints over BigDecimals for this. BigDecimals *are* scaled ints already, so there is no need to be ver careful. Why re-invent the wheel? BigDecimals are not just big floats. – Rudy Velthuis Apr 13 '16 at 22:45
0

looks like using ints was just ill conceived.

I did get it to play right with smaller numbers (the biggest issue was having to again bump up the principal by 100 to keep the correct place holder for when the interest which was (p*100)*(i*100) otherwise it was something *100 being added to the interest which was *10000. Sadly any realistic amount of money (like say 250000 for a house) overflows it before the first loop. Though 200000 makes it all the way to loop 30.

Plus interest rates aren't always hundredths, sometimes they are something like .03875

My code lacks the ability to determine the length and even if it had it bumping that up to an int, and keeping everything else like it (multiplying everything by 100000) would definitely not work.

Props to community for not calling me an idiot though! on Youtube et al, I would have gotten answers that would have put me into a corner crying!

dosmastr
  • 7
  • 5
  • 250000 isn't a realistic amount for a house--not where I live. 250000 might get me a garage. :) I think there's at least one house in my area where even an `int` wouldn't be enough to hold the selling price if you scaled it by 100. Some NBA star bought that. Anyway, you can use `long`. – ajb Apr 13 '16 at 17:59
  • @ajb: depends on the currency and where you live. 250k Euro for a house is quite normal here. – Rudy Velthuis Apr 14 '16 at 07:28
  • @RudyVelthuis Bad, bad me for making assumptions about the currency type. And I should know better because I've been working on code to deal with different currency types just this week. :( I guess we should rule out 250k Japanese yen because I'd have to live in a refrigerator. Anyway, US $250000 is enough to buy a decent house in most of the US. Just not in my neighborhood. – ajb Apr 14 '16 at 14:59
  • you guys are hilarious! and correct. It did throw errors when I scaled it by 100. Some really smart Stackoverflow people should get together and write/compile books of most common issues and solutions... you are being quite helpful in my first programming course, the book just doesn't explain stuff as well as most of you guys. – dosmastr Apr 17 '16 at 19:47