Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
Коллеги, буду благодарен, если кто-то сможет поделиться соображениями по данному поводу.

Дано: Cache 2012.2.5 - 2015.1.2.

Локаль: ^%SYS("LOCALE","CURRENT")="ruw8"
Таблица сортировки: Cyrillic2 или Cache standard (не важно).

Вопрос: Есть ли разумное объяснение такой сортировке?
 kill b
 
set a=1E30,b(+a)=1,b(+a_"1")=3,b(+a_"1a")="3a"
 
set a=3E30,b(+a)=2,b(+a_"1")=4,b(+a_"1a")="4a"
 
set b($c(2))="??"
 
zwrite b

b(1000000000000000000000000000000)=1
b(3000000000000000000000000000000)=2
b("10000000000000000000000000000001")=3
b("30000000000000000000000000000001")=4
b($c(2))="??"
b("10000000000000000000000000000001a")="3a"
b("30000000000000000000000000000001a")="4a"

При этом стандартная проверка локали:
 kill for i=0:1:127 b($c(i))=i
проходит нормально: сначала числа, потом строки в порядке возрастания кодов ASCII.
15 дек 15, 13:06    [18562215]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
DAiMor
Member

Откуда: Volzhsky -> Moscow -> CZ, Brno
Сообщений: 2539
Alexey Maslov
b("10000000000000000000000000000001")=3
b("30000000000000000000000000000001")=4

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

но это уже вопрос к IS, корректно ли что строки которые только с числами сортируются как числа, а не как строки

у меня так же сортируется
Cache for Windows (x86-64) 2016.1 (Build 596U) Mon Nov 9 2015 21:12:55 EST
15 дек 15, 13:17    [18562271]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
ну я
Member

Откуда: Stalingrad
Сообщений: 1149
Alexey Maslov,

USER>kill b

USER>set b(+a_"1")=3,b(+a_"1a")="3a"

USER>set b(+a_"1")=4,b(+a_"1a")="4a"

USER>set b($c(2))="??"

USER>zwrite b
b("30000000000000000000000000000001")=4
b($c(2))="??"
b("30000000000000000000000000000001a")="4a"

USER>w $zv
Cache for Windows (x86-64) 2008.2 (Build 506) Thu Sep 4 2008 11:07:26 EDT

У меня с записями маркированными как 3 и 3а что-то куда-то вообще уехало...
15 дек 15, 13:31    [18562405]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
DAiMor,
Вот и мне так показалось. Кстати, результат такой же, даже если подобное "псевдочисло" вызывает числовое переполнение, например:
USER>j=310,n=$tr($j("",j)," ",1) set b(n)=zw b
b(1000000000000000000000000000000)=1
b(3000000000000000000000000000000)=2
b("10000000000000000000000000000001")=3
b("30000000000000000000000000000001")=4
b("11111111111111111111111111111111111111...111")=310
b($c(2))="c2"
b("10000000000000000000000000000001a")="3a"
b("30000000000000000000000000000001a")="4a"

USER>n=+n

n=+n
^
<MAXNUMBER>
15 дек 15, 13:31    [18562407]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
ну я
Member

Откуда: Stalingrad
Сообщений: 1149
сорри, только заметил что в тесте не менял a
15 дек 15, 13:32    [18562417]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
ну я,

"а что нам скажет товарищ MiniM"?

Проще выполнять однострочник:
a=1E30,b(+a)=1,b(+a_"1")=3,b(+a_"1a")="3a",a=3E30,b(+a)=2,b(+a_"1")=4,b(+a_"1a")="4a",b($c(2))="c2" zwrite b
15 дек 15, 13:36    [18562448]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
ну я
Member

Откуда: Stalingrad
Сообщений: 1149
b(1E+30)=1
b(3E+30)=2
b("&#9787;")="c2"
b("1E+301")=3
b("1E+301a")="3a"
b("3E+301")=4
b("3E+301a")="4a"
15 дек 15, 13:47    [18562539]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
ну я
Member

Откуда: Stalingrad
Сообщений: 1149
b("&#9787;")="c2"
Тут в индексе в досовой кодировке рожица должна быть.
15 дек 15, 13:49    [18562546]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
ну я,

спасибо, в MiniM сортируется, как и ожидается, хотя, похоже, есть (другая) ошибка. Согласно Стандарту, унарный плюс (как и любая арифметическая операция) должен привести число к каноническому виду, e.g.
USER>set a="1E30" write +a,!,+a_"1"
1000000000000000000000000000000
10000000000000000000000000000001
15 дек 15, 13:58    [18562608]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Александр Коблов
Member

Откуда: Краснодар, Москва
Сообщений: 240
Это наверное не объяснение, но в документации есть абзац про порядок сортировки чисел и строк: Numeric and String-Valued Subscripts

Обратите внимание, что порядок сортировки строк не обязательно совпадает с порядком кодов символов:

USER>set ^a("текст")=1

USER>set ^a("ТЕКСТ")=1

USER>write ##class(%Collate).LogicalToDisplay(##class(%GlobalEdit).Open("a").Collation)
Cyrillic2

USER>zwrite ^a
^a("текст")=1
^a("ТЕКСТ")=1

USER>write $Ascii("т")
242
USER>write $Ascii("Т")
210
15 дек 15, 14:01    [18562625]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
Александр Коблов,

спасибо, об этом знаем :) не случайно ведь привёл:
При этом стандартная проверка локали:
kill for i=0:1:127 b($c(i))=
проходит нормально: сначала числа, потом строки в порядке возрастания кодов ASCII.
К тому же в пределах первой половины таблицы ASCII никаких чудес быть не должно (согласно Стандарту языка ISO/M).

В качестве попытки объяснения можно было бы привести результат выполнения $isvalidnum, однако:
 set j=310,n=$tr($j("",j)," ",1)
 
for i="10000000000000000000000000000001","30000000000000000000000000000001",
  
w $isvalidnum(i)_" $length(i)="_$l(i)_" i="_i,! ;_" i=+i:"_(i=+i),!
}

1 $length(i)=32 i=10000000000000000000000000000001
1 $length(i)=32 i=30000000000000000000000000000001
0 $length(i)=310 i=111...111111111111111111111111111111
при этом n, как было показано ранее, тоже сортируется в индексе как число.
15 дек 15, 14:16    [18562757]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
Коллеги,
понимаю, что, наверное, уже надоел, и, конечно, обращусь в WRC, но может кто-нибудь для статистики выполнить пресловутый однострочник в MSM?
Я почти уверен в результате, но всё же...
 a=1E30,b(+a)=1,b(+a_"1")=3,b(+a_"1a")="3a",a=3E30,b(+a)=2,b(+a_"1")=4,b(+a_"1a")="4a",b($c(2))="c2" zwrite b
15 дек 15, 15:38    [18563393]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
ну я
Member

Откуда: Stalingrad
Сообщений: 1149
Alexey Maslov,

MSM for Windows NT, Version 4.4.1 (RC-1)  Line #1  UCI: ******* Job #3
>a=1E30,b(+a)=1,b(+a_"1")=3,b(+a_"1a")="3a",a=3E30,b(+a)=2,b(+a_"1")=4,b(+a_"1a")="4a",b($c(2))="c2" zwrite b
b(1000000000000000000000000000000)=1
b(3000000000000000000000000000000)=2
b("")="c2"
b("10000000000000000000000000000001")=3
b("10000000000000000000000000000001a")="3a"
b("30000000000000000000000000000001")=4
b("30000000000000000000000000000001a")="4a"
15 дек 15, 15:41    [18563420]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
Уже подзабыл, дружит ли MSM с управляющими в индексах, если нет, то последнее присваивание (b($c(2))="c2") можно смело выкинуть, т.к. $c(2) в Cache сортируется правильно и не влияет на суть примера.
15 дек 15, 15:44    [18563454]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
ну я, ещё раз спасибо.

Похоже, у основных "M-соседей" сортируется правильно, бяка только в Cache. Не имею доступа к экзотике типа M21 и MumpsV1, но это уже не столь важно.
15 дек 15, 15:49    [18563486]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Valeriu
Member

Откуда: Chisinau
Сообщений: 1992
Alexey Maslov,

GTM>a=1E30,b(+a)=1,b(+a_"1")=3,b(+a_"1a")="3a",a=3E30,b(+a)=2,b(+a_"1")=4,b(+a_"1a")="4a",b($c(2))="c2" zwrite b
b(1000000000000000000000000000000)=1
b(3000000000000000000000000000000)=2
b($C(2))="c2"
b("10000000000000000000000000000001")=3
b("10000000000000000000000000000001a")="3a"
b("30000000000000000000000000000001")=4
b("30000000000000000000000000000001a")="4a"

GTM>
15 дек 15, 16:01    [18563574]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
Valeriu,

спасибо.
15 дек 15, 16:44    [18563817]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3103
Блог
Alexey Maslov
Вопрос: Есть ли разумное объяснение такой сортировке?
Пока всё согласно документации:
Поэтому первые три сортируются как числа, а вторые - как строки:

b
b(12345678901234567891)=1
b("12345678901234567891")=2
b("11345678901234567891")=3
zw b
!
b
b(012345678901234567891)=1
b("012345678901234567891")=2
b("011345678901234567891")=3
zw b

b("11345678901234567891")=3
b(12345678901234567890)=1
b("12345678901234567891")=2

b(12345678901234567890)=1
b("011345678901234567891")=3
b("012345678901234567891")=2
Именно поэтому "1111111111111111...11111111111111111" сортируется как число, а не строка, хотя это строка.
Но достаточно жёстко указать Caché воспринимать её как строку, как она уже сортируется как строка, например:
b($c(0))=$c(0)
j=110,b($tr($j("",j)," ",1))=j
j=110,b($tr($j("",j)," ","0"))=j
zw b

b("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")=110
b($c(0))=$c(0)
b("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")=110

b($c(0))=$c(0)
j=110,b("0"_$tr($j("",j-1)," ",1))=; указываем явно строчную сортировку
j=110,b($tr($j("",j)," ","0"))=j
zw b

b($c(0))=$c(0)
b("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")=110
b("01111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")=110
15 дек 15, 17:10    [18563929]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
servit,

у вас другой код, и другие результаты. Свой пример я ещё немного доработал:
a=1E30,b(+a)=1,b(+a_"11")=11,b(+a_"111")=111,b(+a_"1a")="3a",a=3E30,b(+a)=3,b(+a_"33")=33,b(+a_"333")=333,b(+a_"1a")="4a" zwrite b
b(1000000000000000000000000000000)=1
b(3000000000000000000000000000000)=3
b("100000000000000000000000000000011")=11
b("300000000000000000000000000000033")=33
b("1000000000000000000000000000000111")=111
b("3000000000000000000000000000000333")=333
b("10000000000000000000000000000001a")="3a"
b("30000000000000000000000000000001a")="4a"
Видите, что получается? По документации должно быть 2 интервала сортировки:
1) числа - сортируются как числа
2) не числа - сортируются алфавитно.

А мы видим три:
1) числа - сортируются как числа (1-3)
1*) "псевдочисла" - сортируются как числа (11-333)
2) не числа - сортируются алфавитно (3a-4a).

(Временно) прекращаю обсуждение, т.к. открыл проблему в WRC. Если ISC не будет возражать, отпишусь о результатах.
15 дек 15, 18:04    [18564206]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
servit,

напоследок приведу модифицированный пример без комментариев.
set j=310,n=$tr($j("",j)," ",1),b(n)="Over1",n=$tr($j("",j)," ",2),b(n)="Over2",n=$tr($j("",j+1)," ",1),b(n)="Over11" a=1E30,b(+a)=1,b(+a_"11")=11,b(+a_"111")=111,b(+a_"1a")="3a",a=3E30,b(+a)=3,b(+a_"33")=33,b(+a_"333")=333,b(+a_"1a")="4a" x="" x=$o(b(x)) q:x=""  w $j(b(x),10),"  isvalidnum? ",$isvalidnum(xtry {"  x=+x? ",x=+x,"  x-1+1=x? ",x-1+1=x,!catch w $ze,! }}

1 isvalidnum? 1 x=+x? 1 x-1+1=x? 1
3 isvalidnum? 1 x=+x? 1 x-1+1=x? 1
11 isvalidnum? 1 x=+x? 0 x-1+1=x? 0
33 isvalidnum? 1 x=+x? 0 x-1+1=x? 0
111 isvalidnum? 1 x=+x? 0 x-1+1=x? 0
333 isvalidnum? 1 x=+x? 0 x-1+1=x? 0
Over1 isvalidnum? 0 x=+x? <MAXNUMBER>
Over2 isvalidnum? 0 x=+x? <MAXNUMBER>
Over11 isvalidnum? 0 x=+x? <MAXNUMBER>
3a isvalidnum? 0 x=+x? 0 x-1+1=x? 0
4a isvalidnum? 0 x=+x? 0 x-1+1=x? 0
15 дек 15, 18:36    [18564391]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
eduard93
Member

Откуда:
Сообщений: 157
Alexey Maslov, у вас числа больше максимально возможного целого числа в Cache 2^63-1 = 9223372036854775807.
15 дек 15, 21:51    [18565205]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
eduard93, правильно. Тогда вопрос, почему Cache считает их числами:
PERF>w $isvalidnum(9223372036854775808)
1
PERF>w $isvalidnum(19223372036854775808)
1
если произошёл выход за рамки диапазона чисел?
16 дек 15, 08:05    [18565942]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
Возможно, дело в этом:
Cache ObjectScript Reference
$DOUBLE
Note:
A Cache numeric string literal that exceeds the min/max range supported by Cache floating point data types (for example, “1E128”) is automatically converted to an IEEE double-precision floating point number. This conversion is only performed on numeric literals; it is not performed on the results of mathematical operations. This automatic conversion can be controlled on a per-process basis using the TruncateOverflow() method of the %SYSTEM.Process class. The system-wide default behavior can be established by setting the TruncateOverflow property of the Config.Miscellaneous class.
Это объясняет поведение $isvalidnum, но не оправдывает сортировку, которая должна подчиняться не внутренней функции, а Стандарту, который в этой важной части, как мы вчера увидели, неплохо соблюдается в других М-системах.
16 дек 15, 08:24    [18565972]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Timur Safin
Member

Откуда:
Сообщений: 54
Alexey Maslov,

Какому такому стандарту? :)

(Он был про другой язык, он не активен, он сообществу не нужен и не поддерживается)
16 дек 15, 12:26    [18567146]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
Timur Safin,

тем не менее, в документации немало ссылок на Стандарт ISO 11756-1999 (поиск работает :). Вот, например, в тему:
Routines
When you create routines in Cache, you can choose the programming language for each routine. The choices are as follows:
Cache ObjectScript, which is a superset of the ISO 11756-1999 standard M programming language. If you are an M programmer, you can run your existing M applications on Cache with no change.

Timur Safin
Он был про другой язык, он не активен, он сообществу не нужен и не поддерживается
Расскажите об этом, например, участникам этого сборища, им полезно будет узнать, что они "скорее мертвы, чем живы".

Стоит ли объяснять, зачем нужна обратная совместимость со Стандартом, кстати, весьма хорошо обеспечиваемая в Cache? Случайно найденное мною исключение лишь подтверждает правило :)
16 дек 15, 13:01    [18567305]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
Замыкая круг.
Разработчик в принципе подтвердил моё рассуждение в 18564206, только вот никаких псевдочисел нет: "In ANSI collation, any number (or string that is in canonic numeric form) is collated numerically, before all non-numeric strings."
Причём это не всегда было так, а начиная с какой-то версии (не сказали с какой, но видимо c довольно давней). Не важен ни результат $isvalidnum, ни возможный <MAXNUMBER> при "классической" проверке на число: n=+n.
Не стал бы и писать об этом, но механизм сортировки один из "ядерных", и его непонятное поведение меня встревожило. Теперь успокоили :)

Всем спасибо, кто поучаствовал.
17 дек 15, 19:52    [18574775]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Timur Safin
Member

Откуда:
Сообщений: 54
Alexey Maslov
"In ANSI collation, any number (or string that is in canonic numeric form) is collated numerically, before all non-numeric strings."
Причём это не всегда было так, а начиная с какой-то версии (не сказали с какой, но видимо c довольно давней).

Это с SPJ932 присутствующем в продукте еще с 1993(!) года.
17 дек 15, 23:41    [18575701]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3103
Блог
Alexey Maslov,

Подробное объяснение
10 июн 16, 08:22    [19278797]     Ответить | Цитировать Сообщить модератору
 Re: Почему так сортируются строки?  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1517
servit,

спасибо, правда я и тогда всё понял :). Однако лучше бы для большей понятности автор поста употребил оператор ]], а не ], т.к. ] трактуется как "следует-за в порядке кодов символов без учёта специфики числовой сортировки". Для преодоления этого недостатка и был когда-то добавлен в язык Стандарта ISO/1995 оператор ]] - "следует-за в порядке действующей Collation". Мой старый пример, расширенный примером автора, наглядно показывает разницу:
num 
  
b("12345678901234567870")="Num20 @ S.Hobbs" b("12345678901234567874")="NotNum20 @ S.Hobbs"
  
a=1E30,b(+a)=1,b(+a_"11")=11,b(+a_"111")=111,b(+a_"1a")="3a",a=3E30,b(+a)=3,b(+a_"33")=33,b(+a_"333")=333,b(+a_"1a")="4a"
  
i="",i0="" f  s i=$o(b(i)) q:i=""  "(i]]i0)=",i]]i0," (i]i0)=",i]i0," (i>i0)=",i>i0,?30," " zw b(ii0=i
  
q
+
LEARN>num^ztest
(i]]i0)=1 (i]i0)=1 (i>i0)=1 b(12345678901234567870)="Num20 @ S.Hobbs"
(i]]i0)=1 (i]i0)=1 (i>i0)=0 b("12345678901234567874")="NotNum20 @ S.Hobbs"
(i]]i0)=1 (i]i0)=0 (i>i0)=1 b(1000000000000000000000000000000)=1
(i]]i0)=1 (i]i0)=1 (i>i0)=1 b(3000000000000000000000000000000)=3
(i]]i0)=1 (i]i0)=0 (i>i0)=1 b("100000000000000000000000000000011")=11
(i]]i0)=1 (i]i0)=1 (i>i0)=1 b("300000000000000000000000000000033")=33
(i]]i0)=1 (i]i0)=0 (i>i0)=1 b("1000000000000000000000000000000111")=111
(i]]i0)=1 (i]i0)=1 (i>i0)=1 b("3000000000000000000000000000000333")=333
(i]]i0)=1 (i]i0)=0 (i>i0)=0 b("10000000000000000000000000000001a")="3a"
(i]]i0)=1 (i]i0)=1 (i>i0)=1 b("30000000000000000000000000000001a")="4a"
10 июн 16, 13:57    [19280539]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Ответить