Наступил на грабли, подскажите где туплю

 
Print(3/4);
Print(DoubleToStr(3/4,2));


В первом случае выводит 0, а во втором 0.00

Где проблема?
 
Dezil:

В первом случае выводит 0, а во втором 0.00

Где проблема?


Третьего и четвертого случая нет

Print(3.0/4.0);
Print(DoubleToStr(3.0/4.0,2));
 
Vinin:


Третьего и четвертого случая нет

 

Спасибо, странновато это все)
 
Dezil:
Спасибо, странновато это все)


Странного ничего нет. Есть целые числа, есть действительные (есть еще и всякие другие).

При деление целого на целое получается целое. В остальных случаях нет

 
Vinin:


При деление целого на целое получается целое. 


Вот это и странно с точки зрения реальной жизни
 
Vinin:


Странного ничего нет. Есть целые числа, есть действительные (есть еще и всякие другие).

При деление целого на целое получается целое. В остальных случаях нет

Мне другое непонятно, почему в этом языке сделано так: что, если даже результат определён типом double, всё равно результат = 0. Казалось бы определив Rez как double мы как бы косвенно даём указание, что дробную часть надо сохранять.

 

double Rez;
Rez=3/4;
Print(Rez);
 
khorosh:

Мне другое непонятно, почему в этом языке сделано так: что, если даже результат определён типом double, всё равно результат = 0. Казалось бы определив Rez как double мы как бы косвенно даём указание, что дробную часть надо сохранять.

 

 


Потому, что деление-то вы делаете ЦЕЛЫХ чисел, а уж потом помещаете их в переменную определенную как вещественный тип.

 
ktest0:


Потому, что деление-то вы делаете ЦЕЛЫХ чисел, а уж потом помещаете их в переменную определенную как вещественный тип.

 

Ну и что?- можно же было сделать в языке так, если тип переменной результата не определён приводить его к типу в зависимости от типов делимого и делителя. А если определён,  как double заранее, то почему бы не сохранить дробную часть?
 
khorosh:
Ну и что?- можно же было сделать в языке так, если тип переменной результата не определён приводить его к типу в зависимости от типов делимого и делителя. А если определён,  как double заранее, то почему бы не сохранить дробную часть?

Это неправильно,так как команд процессора ограниченный набор, и опреации арифметические и пирсваивания не могут выполняться за один процессорный цикл. Ивините, а если вы решите 300 чисел поделить? Как бедному CPU узнать заранее, что вы хотите результат с плавающей точкой, если Вы ему заранее это не сказали?

Надо, чтоб была возможность сделать и так, и этак, поэтому в полноценных языках программирования для таких слуаев предусмотрено явное преобразование типов, т.е. было бы так:

double Rez;
Rez=(double)3/4;

в MQL4 такого нет, но есть возможность эксплуатировать неявное приведение по правилам языка


double Rez;
Rez=3/4.;
то есть, если хотя бы один операнд в выражении имеет тип double, то компилятор обязан привести все остальные к типу double до вычисления выражения, а не после, как если бы они все были int.
 
alsu:

... Как бедному CPU узнать заранее, что вы хотите результат с плавающей точкой, если Вы ему заранее это не сказали?

..

Когда я определил тип Rez как double, я и сказал заранее, что я хочу.
 
khorosh:
Ну и что?- можно же было сделать в языке так, если тип переменной результата не определён приводить его к типу в зависимости от типов делимого и делителя. А если определён,  как double заранее, то почему бы не сохранить дробную часть?

Нет никакого "заранее", действия производятся последовательно:

- сначала деление целого на целое и получение целого результата;

- потом запись целого в переменную типа double, при этом происходит неявное приведение типа.

----------------

Представьте другой случай: Вам надо получить целое от деления целых чисел, а результат сохранить в переменной типа double.

Если хотите сразу получить double, укажите это в операции явно:

int i,j;
double d;

// тут какие-то вычисления
// . . . 

if ( j != 0 )
  d = 1.0 * i / j;
Причина обращения: