Сортировка проблем с TArray <Myrectype> для больших чисел

В чем причина того, что TArray.Sort<Mytype> не работает, когда у меня в сравнении большие числа?

Мой код выглядит следующим образом (Delphiy Tokyo):

Interface

Type 
 RCInd = record
           Num              : Integer;
           Ger              : Integer;           
           Confirmed        : Boolean;
           Total            : Real;
   End;

   TArrInd = TArray<RCInd>;

   Procedure SortInd  (Var PArrayInd  : TArrInd);

Implementation  

Procedure SortInd  (Var PArrayInd  : TArrInd);    
begin
  TArray.Sort<RCInd>( PArrayInd,TComparer<RCInd>.Construct
                       ( function (Const Rec1, Rec2 : RCInd) : Integer 
                         begin
                           Result := - ( Trunc(Rec1.Total) - Trunc(Rec2.Total) );
                         end )
                       );
end;

......

Когда значения Rec1.Total и Rec2.Total находятся в пределах целого числа, эта сортировка работает нормально, НО, когда значения превышают целочисленные пределы, процедура сортировки не работает! Он генерирует несортированный набор данных в PArrayInd.

Что здесь происходит?

Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
3
0
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в переполнении. Реальные значения выходят за пределы целочисленного типа.

Функция сравнения предназначена для возврата отрицательного значения, чтобы указать меньше, а положительного значения. Укажите больше и ноль для обозначения равенства. Использование арифметики является причиной вашей проблемы, ведущей к переполнению. Вместо этого используйте операторы сравнения.

function(const Rec1, Rec2: RCInd): Integer
begin
  if Rec1.Total < Rec2.Total then
    Result := 1
  else if Rec1.Total > Rec2.Total then
    Result := -1
  else
    Result := 0;
end;

Проблема в этом вопросе заключается в попытке уместить реальное значение в целое число, но даже если у вас есть целочисленные данные, арифметика не должна использоваться для функций сравнения. Рассмотрим выражение

Low(Integer) - 1

Это приводит к переполнению. Как правило, всегда используйте операторы сравнения для реализации функций сравнения.

вот оно что! Я изменил функцию, как вы предложили, и она сработала! Большое спасибо !

JRG 30.06.2018 07:45

Другие вопросы по теме