Ошибка приведения типов в операциях "*=" и "/=".

 

Почему-то операция "*=" не работает с числами двойной точности.

int X = 1234;

X *= 0.1;

У меня после этого любой X превращается в ноль.

Но деление на 10 работает.

Это так специально задумано? 

 

Да уж, сюрприз. Похоже на то, что правила приведения типов для операции "*=" отождествлены с оными для обычной операции присваивания - без учета того, что выражение справа на самом деле не 0.1, а Х*0.1.

P.S. Вадим, как-то ты уж слишком смело пошутил с разными типами, лучше так не делать. Но это все равно не фича, а баг. Вот еще пример:

int x = 1234;
x /= 10.8;
 
Mathemat >>:

Вот еще пример:

int x = 1234;
x /= 10.8;

Ага.. Тоже самое, но на оборот :-))

 
Вадим, ты бы изменил название темы, чтобы разработчики ее заметили. Такого жучка надо фиксить срочно, в ближайшем билде.
 

Вы же это с int'eджером делаете, измените на double, и все ОК будет.

	double x=1324;
	x*=0.1;
 

Это-то ясно сразу, что сочетание таких типов данных, как у Zhunko, мягко говоря, не слишком целесообразно. Тем не менее, согласись, что это все же баг, который непросто будет выловить в коде...

 
Mathemat >>:

Это-то ясно сразу, что сочетание таких типов данных, как у Zhunko, мягко говоря, не слишком целесообразно. Тем не менее, согласись, что это все же баг, который непросто будет выловить в коде...

Я очевидно что-то не понимаю, бага я не вижу. Он не извеняет тип даного исходного числа, и видимо производит операцию MathRound() над числом на которое умножается. Берет целую часть числа, и умножает ее на исходное. 5 * 0.1=0; 5 * 2.3=10. А чтобы отлавливать, надо такие места при компиляции отмечать либо как ошибку, либо как предупреждение.

 

Это баг. Как должны производиться вычисления в строке X *= 0.1?


1. Анализируем всю строку целиком и видим операцию "*=", говорящую нам о том, что это на самом деле сокращенная запись умножения.

2. Преобразуем строку в полный, несокращенный вид: Х = Х * 0.1.

3. Проводим вычисления справа, как положено, и получаем 123.4.

4. Приводим тип - с учетом того, что Х слева целое, и присваиваем этот результат переменной Х. Получаем 123 - правильный ответ.

 
void start()
 {
  int X = 1234;
  int Y = 4321;
  X *=0.1;
  Y /= 10.5;
  Comment ("X = ", X, "\nY = ", Y);
 }

В случаях умножения, любое число превращается в ноль. Т.е. 0.1 = 0. Приводится к целому типу.

В случаях деления, приведения типа к double тоже не происходит. Делит на 10.

Получается, что правая сторона приводится к левой.

 

Культурный человек не будет применять Си в MQL-4

вай вай, ну спасибо,

а я то!, а у меня то! везде берегся, спецназ учитывал, сложение проверил, а умножение нет((
Радость то какая, сколько ТС и каких (!) из мусорной корзины удасться теперь Реабилитировать!

 
Korey >>: Культурный человек не будет применять Си в MQL-4

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

Второе: Си создавался извращенцами и для извращенцев (судя по тем выражениям и конструкциям, которые в нем возможны).

Третье: Вадим, у меня нет оснований считать тебя некультурным человеком, но, по всей видимости, ты при этом еще и крайний извращенец: я не могу найти разумных доводов в пользу умножения целого на 0.1 (не деления на целое 10, а именно умножения на 0.1!), присваивания результата тому же целому, да еще и дальнейшего сокращения этой записи. Вообще говоря, никто и не запрещал использовать MQL-IV извращенцам, хоть и культурным...