Missing Math Function

Alex69

Member
Licensed User
Longtime User
Hi,
Function MOD returns only the remainder :sign0148:.

What I mean: If you try calculating hours in minutes , you expect this:

(60 MOD 60 ) = 1 (hour)

but you receive 0

It is very confusing because (180 mod 60) also return 0 :BangHead: while you expect 3 (hours)!!!

Please help

Alex
 

Informatix

Expert
Licensed User
Longtime User
Hi,
Function MOD returns only the remainder :sign0148:.

What I mean: If you try calculating hours in minutes , you expect this:

(60 MOD 60 ) = 1 (hour)

but you receive 0

It is very confusing because (180 mod 60) also return 0 :BangHead: while you expect 3 (hours)!!!

Please help

Alex

"Mod" in all languages that I known returns the remainder of a division. So there's nothing strange here.
180 / 60 returns 3. You don't need "mod" to find that.
 

mc73

Well-Known Member
Licensed User
Longtime User
Informatix is right of course. You should simply divide, after dimming your result as int, in order to get the integer part.
 

krokiz

Member
Licensed User
Longtime User
More about Integer division

I think they are confusing Mod with what some languages call Integer Division (Usually a \). It is the other half of Mod and just returns the division without fraction or remainder (And no rounding).

I used to program in Basic back in 1985, and The Apple][ Basic had both integers and floats. Nevertheless, The integer Basic (for Apple][) had only Integer division. Simple days! I was wondering if there is (going to be) integer division between 2 integers in Basic4Android, something like the \ operator, BECAUSE if you look into main.java file's fragment:

public static int _div(int _a,int _b) throws Exception{
int _c = 0;
//BA.debugLineNum = 3384;BA.debugLine="Sub div (a As Int, b As Int) As Int";
//BA.debugLineNum = 3385;BA.debugLine="Dim c As Int";
_c = 0;
//BA.debugLineNum = 3386;BA.debugLine="c = a / b";
_c = (int)(_a/(double)_b);
//BA.debugLineNum = 3387;BA.debugLine="Return c";
if (true) return _c;
//BA.debugLineNum = 3388;BA.debugLine="End Sub";
return 0;
}

, you will see the division between (note!) 2 integers is actually division of an integer to a DOUBLE !! WHY is that? Is it some kind of a must, that JAVA dictates?? I doubt this is any faster than simply divide intc = (int)(_a/_b); !!

Please, consider integer division between 2 integers. It should not be hard to implement.
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
Currently there isn't an integer division in Basic4android.

You can use Floor(a/b) to implement an integer division.

Since I reported to you that big loops are slow in B4A because everything is converted to double, you gave no explanation about this conversion from integers to doubles. For me, the reason is not obvious at all.
We all know that doubles are slow and use more memory, so why using them?
In a game, in one second, it is not uncommon to do dozens of thousands of computation and using doubles instead of integers is not trivial.
After benchmarking, I estimate that B4A is 33% slower than the same code written in Java when integers are computed inside a loop.
Example of code of one of my benchmarks:
B4X:
public void RunTestB4A(final int LoopCount)
{
      long startTime = System.currentTimeMillis();
      int _a = 0;
      int _b = 0;
      int _c = 0;
      _a = (int)(5);
      _b = (int)(10);
      _c = 0;
      int _i = 0;
      final double step1 = 1;
      final double limit1 = (int)(LoopCount);
      for (_i = (int)(0); (step1 > 0 && _i <= limit1) || (step1 < 0 && _i >= limit1); _i += step1) {
         _c = (int)(_a+_b);
         _c = (int)(_c/(double)_b);
      }
      BA.Log("Elapsed (B4A version) = " + (System.currentTimeMillis() - startTime));
      BA.Log("C = " + _c);
}

public void RunTestJava(final int LoopCount)
   {
      long startTime = System.currentTimeMillis();
      int _a = 5;
      int _b = 10;
      int _c = 0;
      final int step1 = 1;
      for (int _i = 0; _i <= LoopCount; _i += step1) {
         _c = _a+_b;
         _c = _c/_b;
      }
      BA.Log("Elapsed (Java version) = " + (System.currentTimeMillis() - startTime));
      BA.Log("C = " + _c);
}
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The question is what is expected when someone writes a calculation such as:
B4X:
Log(3 / 5)
Most developers will expect it to print 0.6. Not 0. Which is the result of integer division.

It is possible to add an integer division operator in the future. I only wrote that currently there isn't such an operator. BTW, the FOR loop with integers (when possible) discussed in the past was not forgotten. It is still in the planned features list.
 

krokiz

Member
Licensed User
Longtime User
Integer division

Interesting related blog that I just found now: The History of Python: The Problem with Integer Division

From my experience, the default integer division in languages such as Java is a huge cause of bugs.

Since my first days in Pascal back in 1986, I knew that when I wanted to use a real and integer variables or constants in an expression, I would get a result of type REAL. And respectively, when I use only integers, the result would be an integer, no matter what (including the threat of passing over integer margins which were -32768..32767 back in the days ;) ). Later on in Delphi we all got integers of 4 bytes length (-2*147*483*648..2*147*483*647), and we became more relaxed: "my variables' values will be small enough, they will not stray that far", still we all should have pay attention about this not to happen. Now that we got type DOUBLE (8bytes +/- 1.7e +/- 308 (~15 digits)) we are obliged to have our integer variables silently converted to DOUBLEs when being used in pure integer expressions. But what we can do: Either we could wait for the '\' operator, OR (which would be the best side effect) we must try our best to write programs that NEED to USE REAL DIVISION, that would run VERY fast on VERY slow Android devices, or better yet, on already slow AndroidVirtualDevices (AVD) with no hardware/OpenGL/Video acceleration abilities (in my case: Microsoft Virtual PC + WindowsXP emulated + AVD). Future will tell.
Best regards to you all. Krokiz
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
@Informatix, unless you are running loops with more than 200k iterations it will be very hard to see any difference. You can also change to a while loop:
B4X:
Dim i = 0 As Int
Do While i < 1000000
   i = i + 1
   '....
Loop
The above code is the fastest possible code (in Java or B4A).

About the integer division. I'm not really familiar with Pascal. However according to this reference: Pascal Language Reference: 4 - Assignments and Operators

Your statement is wrong.
And respectively, when I use only integers, the result would be an integer, no matter what

The / operator returns a 'real' value. Pascal does have an integer division operator: div.
 

krokiz

Member
Licensed User
Longtime User
....

About the integer division. I'm not really familiar with Pascal. However according to this reference: Pascal Language Reference: 4 - Assignments and Operators

Your statement is wrong.


The / operator returns a 'real' value. Pascal does have an integer division operator: div.

Hi Erel,
I started writing a long answer to your post, but abandoned it.
The short conclusion for me is: If one needs an integer division of two integers, he/she deserves it. Just consider the \ operator between two integers without converting one of them to double and back to int.

int1 = (int)(int2/(double)2);

or better yet

int1 = (int)(int2/2)

Multiplication and division in Java

"... Floats and doubles are multiplied and divided in exactly the same way. When faced with an inexact integer division, Java rounds the result down. For instance dividing 10 by 3 produces 3. "

Best regards: Krokiz
 

Informatix

Expert
Licensed User
Longtime User
@Informatix, unless you are running loops with more than 200k iterations it will be very hard to see any difference.

I agree that in most loops it's not significant, but in some apps where you do a lot of computations, like games, the number of iterations per second can quickly become huge. And when your app uses a physics engine like JBox2D, all your computations must be done in the fixed time step between each frame. As the physics engine will let you only a few milliseconds to do your own computations, it's a real challenge on most devices, so every speed gain is not neglectable.

About the "while" optimization, it's very slightly faster than a For loop. I have to create loops with more than 50 000 000 iterations to start seeing differences.

Your statement is wrong.

I'm not the author of the last post.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Just consider the \ operator between two integers without converting one of them to double and back to int.
It will be considered.

I'm not the author of the last post.
Sorry for not being clear. It was part of the integer division discussion (the discussion with krokiz).

About the "while" optimization, it's very slightly faster than a For loop.
From my tests the "while" optimization is the fastest way for such loops. This means that even after I will modify the For loop code, the "while" loop will still be the quickest. This is also true to code written with Java. It will not be faster than the "while" loop.
 

qsrtech

Active Member
Licensed User
Longtime User
I just want to add my two cents. Yes we need an integer divider. Preferably both the "\" and "div". While my apps don't typically need "speed", it is best to keep things consistent, especially when dealing with multiple code bases.
 
Top