Proper code in Java to calculate floor(n^(1/exp)). WIth n and exp both integers - java

How should I write this function. Argument in is in [2,2^60] and exp in [2,60].
QUEST1 : How to avoid the MESSY test ? I could not make it with Big decimal.This is like an exponential version of the old classic bug ( 1 multiply by 3 then divided by 3 is not always 1).
QUEST2 : How to code it if in is much bigger ( 2^90)
See code below. If needed I can post the code that test it all.
/** #param in input
* #param exp exponent >=2
* #return floor[in^(1/exp)] */
public static long floorOk1( final long in , final int exp) {
final long ret = (long) Math.floor(Math.pow(in,1.0/exp));
if ( Math.pow(ret+1,exp) <= in ) CORRECTIONS++; // add 1 needed
return ( Math.pow(ret+1,exp) <=in ) ? ret+1L: ret ;
}
// All OK floorBAD(25 ,2)=5 = floorULP(25 ,2)
// floorULP(125,3)=5 OK ,BUT floorBAD(125,3)=4 (must be 5 as 5^3=125)
// floorULP(24389,3)=28 and floorBAD(24389,3)=28 BOTH WRONG (should be 29 as 29^3= 24389 )
/** (24389,3)->28 is WRONG should be 29 , BUT ( 125/3)=5 ok */
public static long floorULP( final long in , final int exp) {
final double val = Math.pow(in,1.0/exp) ;
return (long) ( Math.floor(val+Math.ulp(val)));
}
/** Arguments (125/3) and (24389,3) -> WRONG results: 1 less than expected. */
public static long floorBAD( final long in , final int exp) { return (long) Math.floor(Math.pow(in,1.0/exp)); }
/** Args(in,exp)= (125 ,3) ==> floorBAD is wrong but floorULP is OK
* Args(in,exp)= (24389,3) ==> floorBAD is wrong AND floorULP also WRONG
* NOTE : WE HAVE 5^3= 125 ; 29^3= 24389 **/
public static void smallDifferenceTest() {
System.out.println(" floorOk1(25,2) =" + floorOk1(25 ,2) + " == BAD(25 ,2)=" + floorBAD(25 ,2) + " Ok=" + (floorBAD(25 ,2)==floorOk1(25 ,2)) ) ;
System.out.println(" floorOk1(25,2) =" + floorOk1(25 ,2) + " == ULP(25 ,2)=" + floorULP(25 ,2) + " Ok=" + (floorULP(25 ,2)==floorOk1(25 ,2)) ) ;
System.out.println(" floorOk1(125,3) =" + floorOk1(125,3) + " != BAD(125 ,3)=" + floorBAD(125,3) + " Ok=" + (floorBAD(125,3)==floorOk1(125,3)) ) ;
System.out.println(" floorOk1(125,3) =" + floorOk1(125,3) + " == ULP(125 ,3)=" + floorULP(125,3) + " Ok=" + (floorULP(125,3)==floorOk1(125,3)) ) ;
System.out.println(" floorOk1(24389,3) =" + floorOk1(24389,3) + " != ULP(24389,3)=" + floorULP(24389,3) + " Ok=" + (floorULP(24389,3)==floorOk1(24389,3)) ) ; ;
System.out.println(" floorOk1(24389,3) =" + floorOk1(24389,3) + " != BAD(24389,3)=" + floorBAD(24389,3) + " Ok=" + (floorBAD(24389,3)==floorOk1(24389,3)) ) ; ;
}
/*
Tests result are:
floorOk1(25,2) =5 == BAD(25 ,2)=5 Ok=true
floorOk1(25,2) =5 == ULP(25 ,2)=5 Ok=true
floorOk1(125,3) =5 != BAD(125 ,3)=4 Ok=false
floorOk1(125,3) =5 == ULP(125 ,3)=5 Ok=true
floorOk1(24389,3) =29 != ULP(24389,3)=28 Ok=false
floorOk1(24389,3) =29 != BAD(24389,3)=28 Ok=false
*/
I mainly tried BigDecimal as an alternative found one solution:
public static long floorDEC( final long in , final int exp) {
return new BigDecimal(Math.pow(in,1.0/exp),MathContext.DECIMAL32).longValue();
}

Related

Why is the integer comparision giving the wrong results? [duplicate]

In Java, what happens when you increment an int (or byte/short/long) beyond it's max value? Does it wrap around to the max negative value?
Does AtomicInteger.getAndIncrement() also behave in the same manner?
From the Java Language Specification section on integer operations:
The built-in integer operators do not
indicate overflow or underflow in any
way.
The results are specified by the language and independent of the JVM version: Integer.MAX_VALUE + 1 == Integer.MIN_VALUE and Integer.MIN_VALUE - 1 == Integer.MAX_VALUE. The same goes for the other integer types.
The atomic integer objects (AtomicInteger, AtomicLong, etc.) use the normal integer operators internally, so getAndDecrement(), etc. behave this way as well.
If you do something like this:
int x = 2147483647;
x++;
If you now print out x, it will have the value -2147483648.
As jterrace says, the Java run-time will "wrap' the result to the Integer.MIN_VALUE of -2147483648.
But that is Mathematically incorrect!
The correct Mathematically answer is 2147483648.
But an 'int' can't have a value of 2147483648.
The 'int' boundaries are -2147483648 to 2147483647
So why doesn't Java throw an exception?
Good question! An Array object would.
But language authors know the scope of their primitive types, so they use the 'wrapping' technique to avoid a costly exception.
You, as a developer, must test for these type boundaries.
A simple test for incrementing would be
if(x++ == Integer.MIN_VALUE)
//boundary exceeded
A simple test for decrementing would be
if(x-- == Integer.MAX_VALUE)
//boundary exceeded
A complete test for both would be
if(x++ == Integer.MIN_VALUE || x-- == Integer.MAX_VALUE)
//boundary exceeded
What happens is an extra bit is added to the furthest right bit and the order decrements as a negatively signed int ... Notice what happens after 'int_32';
int _0 = 0b0000000000000000000000000000000;
int _1 = 0b0000000000000000000000000000001;
int _2 = 0b0000000000000000000000000000010;
int _3 = 0b0000000000000000000000000000100;
int _4 = 0b0000000000000000000000000001000;
int _5 = 0b0000000000000000000000000010000;
int _6 = 0b0000000000000000000000000100000;
int _7 = 0b0000000000000000000000001000000;
int _8 = 0b0000000000000000000000010000000;
int _9 = 0b0000000000000000000000100000000;
int _10 = 0b0000000000000000000001000000000;
int _11 = 0b0000000000000000000010000000000;
int _12 = 0b0000000000000000000100000000000;
int _13 = 0b0000000000000000001000000000000;
int _14 = 0b0000000000000000010000000000000;
int _15 = 0b0000000000000000100000000000000;
int _16 = 0b0000000000000001000000000000000;
int _17 = 0b0000000000000010000000000000000;
int _18 = 0b0000000000000100000000000000000;
int _19 = 0b0000000000001000000000000000000;
int _20 = 0b0000000000010000000000000000000;
int _21 = 0b0000000000100000000000000000000;
int _22 = 0b0000000001000000000000000000000;
int _23 = 0b0000000010000000000000000000000;
int _24 = 0b0000000100000000000000000000000;
int _25 = 0b0000001000000000000000000000000;
int _26 = 0b0000010000000000000000000000000;
int _27 = 0b0000100000000000000000000000000;
int _28 = 0b0001000000000000000000000000000;
int _29 = 0b0010000000000000000000000000000;
int _30 = 0b0100000000000000000000000000000;
int _31 = 0b1000000000000000000000000000000;
int _32 = 0b1111111111111111111111111111111;
int _XX = 0b10000000000000000000000000000000; // numeric overflow.
int _33 = 0b10000000000000000000000000000001;
int _34 = 0b11000000000000000000000000000000;
int _35 = 0b11100000000000000000000000000000;
int _36 = 0b11110000000000000000000000000000;
int _37 = 0b11111000000000000000000000000000;
int _38 = 0b11111100000000000000000000000000;
int _39 = 0b11111110000000000000000000000000;
int _40 = 0b11111111000000000000000000000000;
int _41 = 0b11111111100000000000000000000000;
int _42 = 0b11111111110000000000000000000000;
int _43 = 0b11111111111000000000000000000000;
int _44 = 0b11111111111100000000000000000000;
int _45 = 0b11111111111110000000000000000000;
int _46 = 0b11111111111111000000000000000000;
int _47 = 0b11111111111111100000000000000000;
int _48 = 0b11111111111111110000000000000000;
int _49 = 0b11111111111111111000000000000000;
int _50 = 0b11111111111111111100000000000000;
int _51 = 0b11111111111111111110000000000000;
int _52 = 0b11111111111111111111000000000000;
int _53 = 0b11111111111111111111100000000000;
int _54 = 0b11111111111111111111110000000000;
int _55 = 0b11111111111111111111111000000000;
int _56 = 0b11111111111111111111111100000000;
int _57 = 0b11111111111111111111111110000000;
int _58 = 0b11111111111111111111111111000000;
int _59 = 0b11111111111111111111111111100000;
int _60 = 0b11111111111111111111111111110000;
int _61 = 0b11111111111111111111111111111000;
int _62 = 0b11111111111111111111111111111100;
int _63 = 0b11111111111111111111111111111110;
int _64 = 0b11111111111111111111111111111111;
System.out.println( " _0 = " + _0 );
System.out.println( " _1 = " + _1 );
System.out.println( " _2 = " + _2 );
System.out.println( " _3 = " + _3 );
System.out.println( " _4 = " + _4 );
System.out.println( " _5 = " + _5 );
System.out.println( " _6 = " + _6 );
System.out.println( " _7 = " + _7 );
System.out.println( " _8 = " + _8 );
System.out.println( " _9 = " + _9 );
System.out.println( " _10 = " + _10 );
System.out.println( " _11 = " + _11 );
System.out.println( " _12 = " + _12 );
System.out.println( " _13 = " + _13 );
System.out.println( " _14 = " + _14 );
System.out.println( " _15 = " + _15 );
System.out.println( " _16 = " + _16 );
System.out.println( " _17 = " + _17 );
System.out.println( " _18 = " + _18 );
System.out.println( " _19 = " + _19 );
System.out.println( " _20 = " + _20 );
System.out.println( " _21 = " + _21 );
System.out.println( " _22 = " + _22 );
System.out.println( " _23 = " + _23 );
System.out.println( " _24 = " + _24 );
System.out.println( " _25 = " + _25 );
System.out.println( " _26 = " + _26 );
System.out.println( " _27 = " + _27 );
System.out.println( " _28 = " + _28 );
System.out.println( " _29 = " + _29 );
System.out.println( " _30 = " + _30 );
System.out.println( " _31 = " + _31 );
System.out.println( " _32 = " + _32 );
System.out.println( " _xx = " + _xx ); // -2147483648
System.out.println( " _33 = " + _33 );
System.out.println( " _34 = " + _34 );
System.out.println( " _35 = " + _35 );
System.out.println( " _36 = " + _36 );
System.out.println( " _37 = " + _37 );
System.out.println( " _38 = " + _38 );
System.out.println( " _39 = " + _39 );
System.out.println( " _40 = " + _40 );
System.out.println( " _41 = " + _41 );
System.out.println( " _42 = " + _42 );
System.out.println( " _43 = " + _43 );
System.out.println( " _44 = " + _44 );
System.out.println( " _45 = " + _45 );
System.out.println( " _46 = " + _46 );
System.out.println( " _47 = " + _47 );
System.out.println( " _48 = " + _48 );
System.out.println( " _49 = " + _49 );
System.out.println( " _50 = " + _50 );
System.out.println( " _51 = " + _51 );
System.out.println( " _52 = " + _52 );
System.out.println( " _53 = " + _53 );
System.out.println( " _54 = " + _54 );
System.out.println( " _55 = " + _55 );
System.out.println( " _56 = " + _56 );
System.out.println( " _57 = " + _57 );
System.out.println( " _58 = " + _58 );
System.out.println( " _59 = " + _59 );
System.out.println( " _60 = " + _60 );
System.out.println( " _61 = " + _61 );
System.out.println( " _62 = " + _62 );
System.out.println( " _63 = " + _63 );
System.out.println( " _64 = " + _64 );
If an integer addition overflows, then
the result is the low-order bits of
the mathematical sum as represented in
some sufficiently large
two's-complement format. If overflow
occurs, then the sign of the result is
not the same as the sign of the
mathematical sum of the two operand
values.
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#13510
This is a workaround answer so you can still continue to basically infinite.
I recommend a if(int > nearmax) then pass to new int
Example:
int x = 2000000000;
x++;
int stacker = 0;
if (x > 2000000000)
{
int temp = x;
x = temp - 2000000000
stacker++;
}
then you can unstack when necessary too...
say x = 0
x--;
if (x < 0 && stacker > 0)
{
int temp = x;
x = 2000000000 + temp;//plus because it's negative
stacker--;
}
this gives 2000000000 x 2000000000 and i mean...you could keep doing this so...ya...
of course you could go even further if you want to use negative numbers...
I'm aware that this is a bit of a necropost, but I came across this and I thought I should share what I've done on my end to anyone who wants the "solved" or my attempt at a solve
package main;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Adder {
public static final int DIGITS = 25;
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("/Users/swapnil/IdeaProjects/Sum/src/Sum.txt"));
analyze(input);
}
public static void analyze(Scanner input) {
int lines = 0;
while (input.hasNextLine()) {
String line = input.nextLine();
Scanner tokens = new Scanner(line);
int[] operand = new int[DIGITS];
initAdd(tokens, operand);
while (tokens.hasNext()) {
contAdd(tokens, operand);
}
System.out.print(" = ");
printAsNumber(operand);
System.out.println();
lines++;
}
System.out.println();
System.out.println("Total lines = " + lines);
}
public static int[] getNextOperand(Scanner tokens) {
String number = tokens.next();
int lastDigitIndex = DIGITS - number.length();
int[] nextOp = new int[DIGITS];
for (int i = lastDigitIndex; i < DIGITS; i++) {
nextOp[i] = Character.getNumericValue(number.charAt(i - lastDigitIndex));
}
return nextOp;
}
public static void addColumns(Scanner tokens, int operand[], int nextOp[]) {
for (int i = DIGITS - 1; i >= 0; i--) {
operand[i] += nextOp[i];
if (operand[i] > 9) {
int currentDigit = operand[i] % 10;
operand[i] = currentDigit;
operand[i - 1]++;
}
}
}
public static void initAdd(Scanner tokens, int operand[]) {
int[] nextOp = getNextOperand(tokens);
printAsNumber(nextOp);
addColumns(tokens, operand, nextOp);
}
public static void contAdd(Scanner tokens, int operand[]) {
int[] nextOp = getNextOperand(tokens);
System.out.print(" + ");
printAsNumber(nextOp);
addColumns(tokens, operand, nextOp);
}
public static void printAsNumber(int number[]) {
int lastDigitIndex = DIGITS - 1;
for (int i = 0; i < DIGITS; i++) {
if (number[i] != 0) {
lastDigitIndex = i;
break;
}
}
for (int i = lastDigitIndex; i < DIGITS; i++) {
System.out.print(number[i]);
}
}
}

Calling method on an object, and using same object as parameter for method

I am working on a java program for creating a slot machine. The program works how I want it to but I am not sure if one of my method calls is proper java etiquette. In my main method below, inside my for loop, I call the method rollAndCompare() on the FourTumblers object, machine. This method returns an integer, coin, which represents how much the user won based on the number of tumblers matched. This if-else statement is written in the FourTumblers class. However, I also pass the same machine object as a parameter so that the method can access the tumbler values of the object. Is there a better way to do this? Is this correct?
public static void main(String[] args) {
int coins;
int addtLives;
int bank = 0;
int lives = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Please enter how many games you want to play:");
int num = scan.nextInt();
System.out.println("You have decided to play " + num + " games.\n");
for (int i = 1; i <= num; i++) {
FourTumblers machine = new FourTumblers();
coins = machine.rollAndCompare(machine);
bank += coins;
addtLives = coins/100;
lives += addtLives;
System.out.println("You won " + coins + " coins. That's " + addtLives + " lives.");
System.out.println("You now have a total of " + bank + " coins and " + lives + " lives.\n");
}
scan.close();
}
Here is my rollAndCompare method...
public int rollAndCompare(FourTumblers machine) {
value1 = machine.getValue1();
value2 = machine.getValue2();
value3 = machine.getValue3();
value4 = machine.getValue4();
if ((value1 == value2)&&(value2 == value3)&&(value3 == value4)){
System.out.println(value1 + " | " + value2 + " | " + value3 + " | " + value4);
System.out.println("Jackpot!");
coins = 600;
return coins;
}
else if (((value1 == value2)&&(value2 == value3))||((value1 == value3)&&(value3 == value4))||((value1 == value2)&&(value2 == value4))||((value2 == value3)&&(value3 == value4))){
System.out.println(value1 + " | " + value2 + " | " + value3 + " | " + value4);
coins = 300;
return coins;
}
else if ((value1 == value4)||(value1 == value2)||(value1 == value3)||(value2 == value3)||(value2 == value4)||(value3 == value4)){
System.out.println(value1 + " | " + value2 + " | " + value3 + " | " + value4);
coins = 100;
return coins;
}
else{
System.out.println(value1 + " | " + value2 + " | " + value3 + " | " + value4);
coins = 0;
return coins;
}
}
The times you would want to add an object onto itself in a class is if you are going to compare it with other objects from the same class.
Ex:
public class Sample
{
private String name = "Sample Chocolate";
private int cost = 1;
public boolean compareSample(Sample sample)
{
if (sample.name.equals(name) && cost == sample.cost)
return true;
else
return false;
}
Then from another class:
public class SampleTester
{
public static void main(String[] args)
{
Sample sample1 = new Sample();
Sample sample2 = new Sample();
System.out.println("Are sample one and sample two the same?: " + sample1.compareSample(sample2));
}
}
Otherwise you can simply put nothing inside the parenthesis:
public boolean compareSample()
{
if (name.equals("Sample Chocolate") && cost == 1)
return true;
else
return false;
}
As Ashiquzzman eloquently said: You can call that using this.getValue(), you don't need to pass machine (to be used as machine.getValue()).

Increase percentage by user input in Java

If user input is higher than 100, it increases 5% percent for each unit i.e. 100 or minus return 5%, 101 return 10%, 102 return 15%, so on.
So far I was able to do this:
public class CalculatePercent {
private int numberGiven;
private int finalPerc;
public String numberGiven(int numberGiven) {
this.numberGiven = numberGiven;
if(numberGiven == 100) {
finalPerc=5;
return "The percentage" + " " + "is:" + " " + finalPerc + "%";
}
else if (finalPerc > 100 ) {
}
return finalPerc;
}
}
And this:
import java.util.Scanner;
public class CalculatorApp {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
CalculatePercent p = new CalculatePercent();
System.out.println("Type the number: ");
String usernumber = p.numberGiven(in.nextInt());
System.out.println(usernumber);
}
}
public class CalculatePercent {
private int numberGiven;
private int finalPerc;
public String numberGiven(int numberGiven) {
this.numberGiven = numberGiven;
if (this.numberGiven <= 100) {
finalPerc = 5;
} else if (this.numberGiven > 100) {
finalPerc = 5 * (this.numberGiven - 99);
/*
Why 99 ?
For examaple :
100 - 99 = 1 * 5 = 5%;
101 - 99 = 2 * 5 = 10%;
102 - 99 = 3 * 5 = 15%
soon
*/
}
return "The percentage" + " " + "is:" + " " + finalPerc + "%";
}
}
I think you want something like
return (numberGiven-99)*5
I think what you are looking for is the following method. I am not sure how you are organizing your classes, but the first problem is that your numberGiven method is not returning a string. The second problem is that there are some "magic numbers in here" i.e. 365. I think what you are looking for is something more like this
public String numberGiven(int numberGiven) {
int finalPerc = 5;
if (numberGiven > 100) {
finalPerc += (numberGiven - 100)*5;
}
return "The percentage" + " " + "is:" + " " + finalPerc + "%";
}

Eliminate zero from result (Java)

Okay so I have built a denomination counter for the Indian currency rupees. Say, if you enter Rs. 3453, it gives this output:
Rs 1000 notes: 3
Rs 500 notes: 0
Rs 100 notes: 4
Rs 50 notes: 1
Rs 20 notes: 0
Rs 10 notes: 0
Rs 5 notes: 0
Rs 2 coins: 1
Rs 1 coin: 1
But I want this output and eliminate all the zeros,
Rs 1000 notes: 3
Rs 100 notes: 4
Rs 50 notes: 1
Rs 2 coins: 1
Rs 1 coin: 1
Here's my code:
import java.io.*;
import javax.swing.JOptionPane;
public class denom {
public static void main(String[] args) throws IOException{
String totalRsString;
int totalRs;
totalRsString = JOptionPane.showInputDialog(null, "Enter amount to be converted", "Denomination Conversion", JOptionPane.INFORMATION_MESSAGE);
totalRs = Integer.parseInt(totalRsString);
//Calculations begin here
int thousand, fh, h, f, twenty, t, fi, tw, o;
thousand = totalRs/1000;
int bal = totalRs - (1000*thousand);
fh = bal/500;
bal = bal - (500*fh);
h = bal/100;
bal = bal - (100 * h);
f = bal/50;
bal = bal - (50*f);
twenty = bal/20;
bal = bal - (20*twenty);
t = bal/10;
bal = bal-(10*t);
fi = bal/5;
bal = bal - (5*fi);
tw = bal/2;
bal = bal - (2*tw);
o = bal/1;
bal = bal - (1*o);
//End of calculation
//Print work.
JOptionPane.showMessageDialog(null, "Total Entered is Rs." + totalRsString + "\n" + "\nThousand rupee notes: " + thousand + "\nFive Hundred Notes: " + fh + "\nHundred notes: " + h + "\nFifty notes: " + f + "\nTwenty notes: " + twenty + "\nTen notes: " + t + "\nFive notes: " + fi +
"\nTwo coins: " + tw + "\nOne coins: " + o);
}
}
Rather than building your string as a single expression of the form ... + ... + ..., you can use a StringBuilder (see Javadoc for java.lang.StringBuilder) to assemble it across several statements. For example, something like this:
JOptionPane.showMessageDialog(null, "foo: " + 17 + "\n" + "bar" + 18 + "\n");
can be rewritten like this:
StringBuilder message = new StringBuilder();
message.append("foo: ").append(17).append("\n");
message.append("bar: ").append(18).append("\n");
JOptionPane.showMessageDialog(null, message.toString());
By using this approach, you can wrap any of the individual "append" statements in an if-block that makes sure the value is nonzero before adding it to the string.
As an alternative, consider using an enum to hold the value, kind and count for each form of Currency:
private enum Kind {
Coins, Notes
};
private enum Currency {
// …
Ten(10, Kind.Notes),
Five(5, Kind.Notes),
Two(2, Kind.Coins),
One(1, Kind.Coins);
private int value;
private Kind kind;
private int count;
private Currency(int value, Kind kind) {
this.value = value;
this.kind = kind;
}
};
Then your convert() method can iterate through the Currency instances and return a List<Currency> that includes only non-zero counts.
private static List<Currency> convert(int amount) {
List<Currency> list = new ArrayList<>();
int balance = amount;
for (Currency currency : Currency.values()) {
// update currency.count
// update balance;
if (currency.count != 0) {
list.add(currency);
}
}
return list;
}
Finally, you can loop though the List<Currency> to print the result:
List<Currency> list = convert(3453);
for (Currency currency : list) {
System.out.println("Rs "
+ currency.value + " "
+ currency.kind + ": "
+ currency.count);
}
You need to build the output string step-by-step. If the corresponding number of coins or notes for that specific input is equal to zero, you should skip that element in the final string.
Something like:
string output = "Total Entered is Rs." + totalRsString + "\n";
if(thousand == 0){
output += "\nThousand rupee notes: " + thousand;
}
/* Here you will do the same for the rest of notes and coins */
JOptionsPane.showMessageDialog(null, output);
Well, this is a lazy solution. But it's up to you to implement it in a more elegant way.
try reducing the number of variables you are creating. See the ones which can be reused.
StringBuilder sb = new StringBuilder();
int totalRs = 5500;
int bal = totalRs;
int numNotes =0;
if ((numNotes =bal/1000) > 0){
sb.append("Rs 1000 notes: " + numNotes + "\n");
bal = bal - (1000 * numNotes);
}
if ((numNotes =bal/500) > 0) {
sb.append("Rs 500 notes: " + numNotes + "\n");
bal = bal - (500 * numNotes);
}

Bingo Lyrics Code Java.lang.stringindexoutofbounds?

I am new to programming and I have written a bingo class that types out the lyrics to bingo. Here is the code:
public class BingoLyrics {
String lineOne = "There was a farmer had a dog and Bingo was his name, oh." ;
String lineTwo = "BINGO" ;
String lineThree = "And Bingo was his name, oh." ;
int starCount = 1 ;
public void bingoLyrics ( ) {
while (starCount != 7) {
System.out.println (lineOne) ;
System.out.println (lineTwo + ", " + lineTwo + ", " + lineTwo) ;
System.out.println (lineThree) ;
lineTwo = "*" + (lineTwo.substring(starCount)) ;
if (lineTwo.length() == 4) {
lineTwo = "*" + lineTwo ;
}
else if (lineTwo.length() == 3) {
lineTwo = "**" + lineTwo;
}
else if (lineTwo.length() == 2) {
lineTwo = "***" + lineTwo;
}
else if (lineTwo.length() == 1) {
lineTwo = "****" + lineTwo;
}
starCount = starCount + 1 ;
}
}
}
It works but i get a java.lang.stringindexoutofbounds for the line lineTwo = "*" + (lineTwo.substring(starCount)) ; . Why does it do this? Any way to fix?
You get an StringOutOfBoundsException because at the last iteration of the loop the starCount is 6, but the string is only five characters long. Instead of using a string for line two, you can use a StringBuilder. It's easier because you can replace a char at a specified index.
public class BingoLyrics {
String lineOne = "There was a farmer had a dog and Bingo was his name, oh.";
StringBuilder lineTwo = new StringBuilder("BINGO");
String lineThree = "And Bingo was his name, oh.";
int starCount = 0;
public void bingoLyrics() {
while (starCount < 6) {
System.out.println(lineOne);
System.out.println(lineTwo + ", " + lineTwo + ", " + lineTwo);
System.out.println(lineThree);
lineTwo.replace(starCount, starCount + 1, "*");
starCount = starCount + 1;
}
}
}

Categories

Resources