Неявное преобразование real → integer


#1

Я реализовал себе такое преобразование в стиле C# и доволен. Это можно сделать, причём 4 строчками.


Директива компилятора для отключения проверки индексатора массива
#2

В смысле? С потерей данных? Я бы не был доволен… И потом, что тут реализовывать? Программист сам выбирает между Trunc и Round. Какие еще “четыре строчки” ?


#3

Смотря в каких случаях. Например когда нужно округлить значение или произвести целочисленное деление. Для этого есть div, но я сделал себе operator implicit и в интовую переменную спокойно кладу результат от деления.


#4

Вы не можете сделать себе оператор implicit, потому что в Паскале можно перегружать только имеющиеся операции. Функцию или расширение - можете конечно.


#5

Значит, можете считать меня колдуном :smile: Я же сделал его.


#6

Когда человек утверждает, что он реализовал в программе что-то, что реализовать синтаксически нельзя, его скорее можно счесть не колдуном, а кое-кем другим, чье название имеет такое же окончание, но иное начало, хоть и само слово созвучно )))) Просто код приведите, раз там 4 строки, если это не великий секрет.


#7

Сами попробуйте написать код

Uses System;
Class function Double.operator implicit(d: Double): Int32;
begin
  Result := Convert.ToInt32(d);
End;
Begin
  Var i: Int32 := 5 / 3;
  Console.WriteLine(i);
End.

И почувствуйте себя тем, о ком говорили.


#8

Именно так в 1 из следующих билдов сделать нельзя будет, но всё равно можно так:

function operator implicit(r:real):integer; extensionmethod;
begin
  Result := System.Convert.ToInt32(r);
end;

Вот только в отличии от div - вы тут делаете

Convert.ToInt32(real(5)/real(3))

Это на много медленнее, ибо лишние преобразования + деление чисел с плавающей запятой всегда медленнее.


#9

Я уже жалею, что напомнил про это… Не надо убирать этого, пожалуйста!!!


#10

Ничто не мешает изменить метод или вообще переопределить метод деления, а в его теле написать div. Это, кстати, будет правильнее.


#11

Это уже исправили, до того как вы напомнили. Это давало много конфликтов. Но как я и сказал, это в целом никто не запрещает, если вы хотите себе стрелять в ногу рандомными преобразованиями real к integer - флаг вам в руки.


#12

Вы это называете “сделал себе оператор inmplicit” ? Тогда, простите, у Вас проблемы с семантикой. Вы не имплисит себе сделали, а перегрузили оператор деления /.


#13

Вы издеваетесь? Там может быть любой double. То, что деление его даёт, ещё не значит, что это единственно возможный случай. Про деление писал выше.


#14

А где вы видите перезагрузку оператора деления? И это тоже она?:

function operator implicit(r:real):integer; extensionmethod;
begin
  Result := System.Convert.ToInt32(r);
end;

begin
  var a:integer := 0.0;
end.

Давайте вы будете пробовать компилировать у себя код и эксперементировать перед тем как начинать утверждать))


#15

Да, я невнимательно посмотрел. Вы просто сделали преобразование типа double в integer через Round. Насколько это плохо - Вам уже писали. Удивительно, что наряду с этим Вы печетесь о высокой производительности операций в Паскале.


#16

Нет, всё ещё не достаточно внимательно))) Convert.ToInt32 делает это в стиле C.


Директива компилятора для отключения проверки индексатора массива
#17

Вы дважды невнимательно прочитали. Мне уже сделали замечание и я сказал, что надо перегружать напрямую деление. В теле писать div.


#18

Сергей, как Вам удаётся так быстро отвечать? :joy:


#19

Convert делает преобразование с округлением. Round делает то же самое. Вот примерчик:

function real.operator implicit(r: real) := System.Convert.ToInt32(r);

begin
  var a:=new integer[4] (5/3,3/7,-2.1,-6.9);
  a.Println;
end.

#20

Это к чему?