0

I am trying to initialize different types in initialization expression of simple FOR loop but there is an error - Type mismatch: cannot convert from BigInteger to int; Syntax error on token "bigInt2", delete this token.

I trying for BigInteger but even if I do for primitives then also I get error.

Below is what I am trying.

for (int j = 1, BigInteger bigInt2 = new BigInteger("1"); 
     j < 1000000; j++, bigInt2 = bigInt2.add(bigIntBase)) {

Questions:

  • Am I doing something wrong or it is not allowed?
  • If not allowed then why? I know using different types in the increment expression is allowed.


Work around I know:
I know work around that I can initialize before the FOR loop but it breaks the whole purpose of initialization expression because if that to happen then whole initialization expression could have been removed from FOR loop and developer could have done it before FOR loop.

10
  • 1
    No, there is not. Its just the way that for loops are parsed. Commented Aug 12, 2015 at 14:00
  • @Kayaman What makes you feel that it is not breaking the purpose of initialization expression. All required initialization cannot be done here. Read text after "because" in my answer. Commented Aug 12, 2015 at 14:10
  • @hagrawal Just because the language syntax doesn't allow something you want doesn't make the for loop broken. Especially considering that there are plenty of cases where it'll work perfectly. You claiming that it "breaks" the init expression of a for loop is only your opinion, and as such holds very little value. Commented Aug 12, 2015 at 14:13
  • @Kayaman Did you delete my comment and your comment where you used offensive word? If yes, then why did you do that if you think you were correct in using offensive work, be brave. Commented Aug 12, 2015 at 14:16
  • 1
    I flagged both comments and some moderator deleted them... just be nice brothers! ;) Commented Aug 12, 2015 at 14:27

5 Answers 5

1

As described in JSL §14.14.1:

The basic for statement executes some initialization code, then executes an Expression, a Statement, and some update code repeatedly until the value of the Expression is false.

14.14.1.1. Initialization of for Statement

A for statement is executed by first executing the ForInit code:

If the ForInit code is a list of statement expressions (§14.8), the expressions are evaluated in sequence from left to right; their values, if any, are discarded.

Inside (§14.8) you can find:

If a trick is needed, either an assignment statement (§15.26) or a local variable declaration statement (§14.4) can be used instead.

And reading (§14.4)

Each declarator in a local variable declaration declares one local variable, whose name is the Identifier that appears in the declarator.

So... You can use more than one counter in the statement declaration of a for loop a statement declaration can only have a single type.

So to or create both variables as BigIntegers:

for (
    // definition
    BigInteger j = BigInteger.ONE, 
         bigInt2 = BigInteger.ONE;
    // comparation  
    j.compareTo(BigInteger.valueOf(1000000)) > 0; 
    // increment
    j.add(BigInteger.ONE), bigInt2 = bigInt2.add(bigIntBase)
) {

Or, just manually handle your int counter and loop over BigInteger:

int j = 1;
for (BigInteger bigInt2 = BigInteger.ONE; ;bigInt2 = bigInt2.add(bigIntBase)) {
    // do your stuff inside for loop 

    // manually handle int counter
    if (j>1000000) break;
    else j++;
}
Sign up to request clarification or add additional context in comments.

8 Comments

Thank but I want to use different type. I want to use int for looping and BigInteger for large computation.
I understand, but you cannot use different types in same loop. What you you can do is simulate it. As long as you MUST use BigInteger for large computations, your counter MUST be another BigInteger
Not necessarily. My counting will not be big and can be easily accommodated in an int but computation requires big container. So, I am using int to avoid unnecessary memory waste.
ok, then just handle int counter manually ;D check my update,
Thanks, that answers what I was looking for. Key thing was that FOR loop's initialization expression is based on local variable declaration rules, so different types cannot be defined until ";" is used.
|
1

The synthax you use is for initializing variable of the same type. Like :

int i=0, j=3; //works fine

You cannot instantiate different type of variable like this :

int i=0, double j=3; //does not work

But that is what you are trying to do in your for loop. This cannot work in any way and this is not caused by the for loop. Java does not work like this (even if other languages do).

You will have to use a workaround for what you want to achieve.

Good luck,

Mathias

1 Comment

Thank for your answer, but it doesn't answer what I was looking for.
1

I assume that this for loop will be part of a class... so why not simply add the integer and BigInteger as class properties and leave the type definitions out of the for loop?

Something like this:

class TestClass
{
    protected int j;
    protected BigInteger bigInt2;

    public void testFunction ()
    {
        for (j = 1, bigInt2 = new BigInteger ("1");
             j < 1000000; j++, bigInt2 = bigInt2.add (bigIntBase))
        {
             // Do stuff
        }
    }
}

3 Comments

Thank for your answer, but it doesn't answer what I was looking for.
This gives wider scope than necessary to both j and bigInt2.
Yes, but I did it this way assuming the loop, or similar loops, appear in multiple places requiring the same data types.
1

Why don't you do that :

    for (final Wrapper w = new Wrapper(0, new BigInteger("0"));
             w.stop(1000);
             w.plus(1, bigIntBase))
    {
        //do your weird stuff
    }

With the wrapper class :

public static class Wrapper
{
    private int              i;

    private final BigInteger bigI;

    public Wrapper(final int pI,
                   final BigInteger pBg)
    {
        super();
        i = pI;
        bigI = pBg;
    }

    public void plus(final int dI,
                     final BigInteger bi)
    {
        i += dI;
        bigI.add(bi);
    }

    public boolean stop(final int max)
    {
        return i<max;
    }

     //add getter for i and bigI...
}

It should do the trick no ?

Mathias

2 Comments

Thank. Nice trick, but it is too much for a simple requirement.
This seems like total overkill for this problem.
1

No, it's not allowed.

Relevant quotes from the JLS (14.14):

A for-statement is defined as:

for ( ForInitopt; Expressionopt ; ForUpdateopt ) ...

The initialization part is defined as:

ForInit:
      StatementExpressionList
      LocalVariableDeclaration

StatementExpressionList (14.14 + 14.8) is not what we want, since there's no variable declaration there:

StatementExpressionList:
      StatementExpression
      StatementExpressionList , StatementExpression

StatementExpression:
      Assignment
      PreIncrementExpression
      PreDecrementExpression
      PostIncrementExpression
      PostDecrementExpression
      MethodInvocation
      ClassInstanceCreationExpression

So LocalVariableDeclaration is what you want. This only allows for a single type: (14.4)

LocalVariableDeclaration:
      VariableModifiersopt Type VariableDeclarators

You could follow the same process to determine what is allowable in ForInit and ForUpdate.

Comments

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.