What's with divisions?

 

I have been coding for a while and didn't come across situations where I have to divide numbers. I was trying to do this today and am not able to understand why the reminders are getting lost. Possibly, I am missing some basic rules on operation so any guidance is appreciated.

In the code below, the value that is commented is 1.00, whereas the correct value should be 1.68.

            int num1 = 123;
            int num2 = 73;
            double num3 = num1/num2;
            string str = DoubleToStr(num3,2);
            Comment(str);
 

Hello highrise


integer maths have no decimal point, yes?

although you do 123/73 the value is 1 because anthing that is right of decimal point is chopped. so 1.68 becomes 1

suggest you click this link https://www.mql5.com/en/search?utm_campaign=MQL4.community which is a site search on arithmetic and... start the reading drill.

all will be revealed in short time :o)


and please consider reading the mql4 book.


this page inside the book will help too: Operations and Expressions

on this page you'll see what's involved and also learn about Typecasting, Integer Calculations and vip! is "Order of Operations"

take special note of type datetime which is stored as an integer - meaning you can do maths on this int eg, taking away say 60seconds from TimeCurrent()...



mql4 is very flexible and even if not find a builtin function to use, given the basic language primitives, you can build your own!


enjoy

:o))


btw:

1. using the Print() function is just like Comment() but o/p goes to Terminal (ctrl+T) on the Experts tab

2.

            string str = DoubleToStr(num3,2);
            Comment(str);

No need to make special string variable unless of course plan to reference it again...

            Comment(DoubleToStr(num3,2));

3.

Also, to ease the typing stuff could also declare num1, num2 as type double and:

"Data of double type are printed with 4 decimal digits after point. To output more precisely, use the DoubleToStr() function."

and above applies for both Comment() and Print()

    //so finally, could if wanted to do division and 4 decimal places were enough:
    double num1=123, num2=73;
 
    Comment(num1/num2);
    //and|or
    Print(num1/num2);
 
    //Terminal > Experts tab shows:
    //2008.05.26 16:42:52    testBed GBPUSD,M15: 1.6849
 

try

double num3 = 1.0*num1/num2;

 

Thanks ukt & DxdCn. I am reading the book to enhance my knowledge but meanwhile implemented DxdCn's suggestion and it works great. It is kind of weird though that multiplying a number with 1 would provide different results !

 
You are multiplying with a DOUBLE.
 

highrise,

because 1.0 is type double, data type int is promoted/type cast, to type double allowing decimal value.

as phy said, DOUBLE.... you are not strictly speaking "...multiplying a number with 1 would provide different results "

1 is type int and 1.0 is type double - study (ref.1) and then progress further when you trully understand the basic data types used, otherwise you will continually think that whatever expression you cook up maybe is ok but not actually understand why and worse still, is when nothing works as expected.

So many people think there "as expected" is cast in stone and of course, it is obvious that is compiler or terminal failure... When in actual fact they are working from poor knowledge foundations. Even worse still is when you categorically deny that it could possibly be the fault of your own making. Bitter experience - many here will confirm - is that 99.9% of time system is doing exactly what you told it to do!

.

Must understand that an arithmetic expression makes no assumptions like you do with pencil and paper. Hence, 1 != 1.0 Two different data types, two different formats used in memory storage etc.

So, 1/2.0 looks simple enough yes? Just looking at it and you'd instantly say in mind (maybe ;) "one half"

The actual execution of that simple division is more involved. You have told cpu to do a division that has two different number types. They must be normalized to both be talking the same language and only then can division take place. Since type double has higher precedence than type int (ref.3), the type int is promoted or type cast to type double. Then, the division takes place between two numbers of type double, ok? Then you also gotta consider the destination data type used. So much conversions can be done in an implicit/beHindTheScenes way - a good reason why some coders use identifier names that instantly say what data type they were declared as...

(if interested Hungarian notation is a naming convention in computer programming, in which the name of a variable indicates its type or intended use.)

and of course beg,borrow 'n steal ideas to make up your own blend of naming conventions which float yer boat!

For you to think about is this: what happens when expression like this is executed?

int = int/double;

or double = datetime/int;

hint: (ref.3)

.

further reading to get mind around expression handling in mql4

  1. MQL4 Reference Basics Data types
  2. MQL4 Reference Basics Data types Type casting

  3. MQL4 Reference Basics Operations & Expressions Precedence rules

As a bit of fun - how about starting by understanding all of below and also play around with the code Print() is most valuable function as always shows warts 'n all ;) regardless of what you've decided answer should be!!!

Think about why sometimes result is zero or has no fractional part or how you can play around using various combinations of data types and how results can vary according to combination makeup,...

Is great background and base of one's programming pyramid to understand such things as type casting, precedence, how (...) can alter default left-->right expression evaluation, why it is good to play around and not worry about mistakes or doing harm to PC etc, .... Print() is your window into the workings of mql4 and as seen below is simplicity itself to testout your ideas FAST... F4 and F5 are great time savers and allow you to bounce around between editor and terminal so easily!

.

I say it all time, but by playing around and such, it is you who benifit greatly and is knowledge you keep because you sweated over the discovering of the knowledge, yes?

Anyway... enjoy

:o)

just highlight > copy > paste into a new MetaEditor file and "SaveAs" .mq4 script source file in .../scripts folder > F5 > F4 > Ctrl+N > run script: double click script file name which you'll find in scripts > Ctrl+T > click Experts tab

please do note that below is only in effect foolin around and many more [most likely sensible/meaningful ] combinations etc. can be made up - I not know much, and actually... I do not care to know all the time because I know one vital thing and that is how to use Print() - lol

int start()
{
    datetime dt=TimeCurrent();
    double d=10.1234;
    double dd=3.4321;
    int i=3;
    //volatile
    int ii;
    datetime dtx;
    double dx;

    Print("dt=",dt,", d=",d,", dd=",dd,", i=",i);
    //========
    Print("\"double/int;\", d/i=",d/i);
    //======
    Print("\"int/double;\", i/d=",i/d);
    //========
    ii=dd/d;
    Print("\"int = double/double;\", ii=dd/d; = ",ii);
    //========
    dx=dd/d;
    Print("\"double = double/double;\", dx=dd/d; = ",dx);
    //========
    dx=dt/i;
    Print("\"double = datetime/int;\", dx=dt/i; = ",dx);
    //======
    dx=d/i;
    Print("\"double = double/int;\", dx=d/i; dx=",dx);
    //=======
    dtx=d/i;
    Print("\"datetime = double/int;\", dtx=d/i; dtx=",dtx);
    //=======
    dx=dt/dd;
    Print("\"double = datetime/double;\", dx=dt/dd; dx=",dx);

    bool b=true;
    Print("b=",b);
    Print("b+i=",b+i);
    Print("b+d=",b+d);

    return(0);
}//start()

/*
2008.05.28 09:24:46    test GBPUSD,M30: b+d=11.1234
2008.05.28 09:24:46    test GBPUSD,M30: b+i=4
2008.05.28 09:24:46    test GBPUSD,M30: b=1
2008.05.28 09:24:46    test GBPUSD,M30: "double = datetime/double;", dx=dt/dd; dx=353127905.0727
2008.05.28 09:24:46    test GBPUSD,M30: "datetime = double/int;", dtx=d/i; dtx=3
2008.05.28 09:24:46    test GBPUSD,M30: "double = double/int;", dx=d/i; dx=3.3745
2008.05.28 09:24:46    test GBPUSD,M30: "double = datetime/int;", dx=dt/i; = 403990094
2008.05.28 09:24:46    test GBPUSD,M30: "double = double/double;", dx=dd/d; = 0.339
2008.05.28 09:24:46    test GBPUSD,M30: "int = double/double;", ii=dd/d; = 0
2008.05.28 09:24:46    test GBPUSD,M30: "int/double;", i/d=0.2963
2008.05.28 09:24:46    test GBPUSD,M30: "double/int;", d/i=3.3745
2008.05.28 09:24:46    test GBPUSD,M30: dt=1211970283, d=10.1234, dd=3.4321, i=3
*/
 
Thanks for this good information. It helped me a lot!
Reason: