![]() |
|
ОФФ встроенный язык 1С не умеет умножать. Ø |
☑ | ||
---|---|---|---|---|
0
NS
26.06.05
✎
17:44
|
Напишу и на этом форуме.
Три года назад я указал критическую ошибку во встроенном языке 1С (в арифметике), так она существует до сих пор. Такой текст - не работает Процедура Сформировать() а=1.1; Для в=1 по 1000 цикл сообщить(""+а+"*"+а+"="); м=_GetPerformanceCounter(); а=а*а; м=_GetPerformanceCounter()-м; сообщить(""+а+" "+м+" мс."); а=а-цел(а)+1; Конеццикла; КонецПроцедуры а такой - работает ;-)) Процедура Сформировать() а=1.1; Для в=1 по 1000 цикл сообщить(""+а+"*"+а+"="); м=_GetPerformanceCounter(); а=а*а/1; м=_GetPerformanceCounter()-м; сообщить(""+а+" "+м+" мс."); а=а-цел(а)+1; Конеццикла; КонецПроцедуры ссылка - http://www.forum.mista.ru/topic.php?id=106471& |
|||
1
VZ
26.06.05
✎
19:11
|
Ну ты даешь... Моя хрюня всю памать сожрала (полгига) и шушит черт знает сколько над первой половиною...
|
|||
2
Дурочка 1С
26.06.05
✎
19:20
|
Не знаю про 25 релиз, но вплоть до 23-го скульный релиз скобок арифметических не понимал - в коврик вываливался.
|
|||
3
NS
26.06.05
✎
21:49
|
(1) Случайно заметил, когда Xonix (года три назад) писал.
Подвисала на "Арсаковском" генераторе случайных чисел. Думал 1С за три года эту ошибку исправила. |
|||
4
VZ
26.06.05
✎
23:12
|
(3) Пришлось снять задачу... Еще и скринсейвер долбанный...
Ладно. Придется специально подготовить проверку :) |
|||
5
Дядя Коля
27.06.05
✎
07:52
|
...гхм!
NS: Пора нам у MBS терминологию перенимать: ошибка платформы, найденная при выпуске обновлений - называется ФИЧА. И всё. Сразу всё становится на свои места :))) //представил, как лет через двести на космолете, управляемом хренью на //платформе 1СV17 с чекухой "1С совместимо" молодой астротемперопрограммер //пытается выяснить, почему темпоральный прыжок закончился не возле //Альдебарана, а возле какого-то красного карлика в совсем другом //континууме. А "старший товарищ" говорит ему небрежно: //- ты, сверх-новый, вспомни что ДэКа сказал 27/06/2005!!! //Во класс!!!! Аж дух захватило! // :)))) |
|||
6
jurii
27.06.05
✎
09:31
|
А я вот так из этого косяка выходил: а=окр(а*а, 100)
Хотя теперь вижу: был путь короче... ;) |
|||
7
Lexusss
27.06.05
✎
09:38
|
(0) А в чем смысл сих деяний?
Ты подумай, какую точность он пытается запулить в 1-м случае. Он же гонит это, как фиксированную запятую, т.к. деления - признака перевода в плавающую запятую - нет. А во втором случае гонит все в плавающую запятую и юзает всю мощь блока процессора, отвечающего за плавающую запятую. Ты же не пишешь в 1С, как в других языках программирования, типа Паскаля, сравнение двух дробных величин в виде Абс(ВеличинаА - ВеличинаБ) < Епсилон. А радуешься прелестями фиксированной запятой и пишешь ВеличинаА = ВеличинаБ. Так что это не ошибка, а именно фича. Прикинь, скока кода придется переписывать, если 1С откажется от фиксированной запятой. Не рождена 1С для разложения в ряды руками тупых 1С-ников. Тут истинные программеры нужны. |
|||
8
NS
27.06.05
✎
09:58
|
(7) Уверяю, есть другие языки с таким-же представлением чисел, и там всё нормально.
Переписать умножение - максимум час. |
|||
9
Мура
27.06.05
✎
10:02
|
<><>й±ти°хъбдсщгзхщб°¦бдчщі°хъвз ъµзэщй䦴°хъгд§ъ·зръи°хъизхъедцґ±¦©гµч¬ґзэбзэъезэбдцщжзэщгд¦бзсщбдцъвзэъд°хщ·зтщіз¤ъй°¦бдтщгз ъад§бзэъІзрщгд¦бзЈщбзрщздчъбзчъізръµзэъд°хъґ°хъ·дхъдзсъІзрщгзрбз бз¤ъґдчъґдхъґз¦бзцъґзчъґдхъйдэщІ° џС‚Еа
|
|||
10
Lexusss
27.06.05
✎
10:05
|
(8) Какое условие выставишь для преобразования фикированной в плавающую запятую БЕЗ ТВОЕГО ВЕДОМА? А с твоего ведома - так достаточно написать /1. И все - дальнейшие расчеты идут в плавающей запятой.
Лично мне не нравится, когда система что-то делает без моего ведома. Я вообще не люблю 1С-кое преобразование типов без четких правил и типизаций. То ли в Делфи - сказал число, значи им оно и будет. Тогда таких вопросов не возникло бы. |
|||
11
АРАВС
27.06.05
✎
10:34
|
Я конечно извиняюсь за глупый вопрос , а что такое
GetPerformanceCounter()? |
|||
12
Дурочка 1С
27.06.05
✎
10:39
|
(11) Это стиль такой. При описании глюка использовать недокументированный метод.
|
|||
13
NS
27.06.05
✎
11:05
|
(10) Абсолютно верно, в нормальном языке должн0 хранится число с полной точностью (причем только при умножении, при делении не надо), а при переполнении должна подвисать винда.
И никто не просил преобразовывать в плавующую, просто необходимо ограничить число разрядов (точность) (12) Это не стиль, эти строки можно убрать. Это демонстрация того, что умножение начинает работать всё медленнее и медленнее, вплоть до подвисания винды. |
|||
14
NS
27.06.05
✎
11:18
|
(+13) Другой тест умножения
а=10; Для в=1 по 100 цикл а=а*а; сообщить(а); конеццикла; мало того, что считает неправильно, еще и подвисает. вместо того, чтоб выдать ошибку переполнения. И тут /1 никапельки не спасает. |
|||
15
Дурочка 1С
27.06.05
✎
11:24
|
Не помню как называется число 10^100. Недостижимое число.
Такими числами просто нечего считать. Если даже вплотную заполнить объем всей видимой вселенной самыми маленькими частицами, то получится, кажется, 10^50 или 60 степени. |
|||
16
Lexusss
27.06.05
✎
11:29
|
(14) Какая в баню ошибка переполнения? Учить мат часть. Аппаратно, при таком деле выставится CF, а в регистр пойдет остаток после переполнения. И никакого прерывания переполнения не произойдет. Не нужно это системе отлавливать CF при каждом суммировании, оно же может быть полезным. Проще доверить это делу программисты.
И 1С в случае (14) отбрасывает нули, хотя делает это безусловно коряво. |
|||
17
LDR
27.06.05
✎
11:31
|
(15) насколько помню число атомов водорода во вселенной где-то 10 в 76 степени.
|
|||
18
VZ
27.06.05
✎
11:38
|
Умные вы, ребята. Я вот насколько помню, в случаях нужды в особом длинном представлении числа и операций с ним всегда писАлись для этого специальные процедуры...
|
|||
19
Lexusss
27.06.05
✎
11:44
|
(17) Десяток порядков туда-сюда, где-то так. :-)
(18) А для 1С надо писать специальные процедуры для укорачиания представления. |
|||
20
NS
27.06.05
✎
12:05
|
Я не понимаю, о чем спор.
При умножении система виснуть не должна в любом случае. И это главное. ..... Зачем хранить всю точность при умножении, если при делении она не хранится? Даже калькулятор и т.д. при переполнении (это по поводу 10 в степени) выдает ошибку переполнения, но никак не сбрасывает в единицу, и тем более не виснет. (16) А мат часть нужно учить тебе. Какое суммирование? Мы говорим об умножении. Математику учил? Разницу видишь? |
|||
21
АЛьФ
27.06.05
✎
12:08
|
Переписать арифметику в 1С - нет проблем, все функции доступны для перехвата. Кто-нибудь возьмется?
|
|||
22
Zubr
27.06.05
✎
12:14
|
(15) Число называется гугол (google)
|
|||
23
KVIK
27.06.05
✎
12:17
|
(15) "гугол" оно называется :)
|
|||
24
IAm
27.06.05
✎
12:20
|
Легче длл сделать обычную а не функция перехватывать. Со строками тоже подвисает, при составлении длинной строки (200 тыс. знаков 1С подвисает на несколько секунд), сделал длл на бейсике, пользовался ею.
|
|||
25
KVIK
27.06.05
✎
12:21
|
(22) по английски "googol", а "google" это поисковик называется :P
|
|||
26
АЛьФ
27.06.05
✎
12:23
|
2(24) Не "легче", но можно и так.
|
|||
27
Lexusss
27.06.05
✎
12:33
|
(20) Она не подвисает, просто компьютер у тебя слабый. Постать Крей, распараллель как следует 1С-ный алгоритм и будет тебе счастье :-)
А на счет флага - так при умножении результат выдается в 2 регистра при множителях по 1. Соответственно если в начале у тебя размер результата 10, то уже через 10 итераций будет полный пипец, а не размер операндов. |
|||
28
NS
27.06.05
✎
15:12
|
Посмотрел подробней.
1С при операциях "+","-","*" хранит полную точность (с включением тормозов и постепенным подвисаниям) Причем над этими числами корректно работают операции сравнения. "%" над такими числами (длинными) работает некорректно. "/" округляет по хитрому алгоритму (в зависимости от точности делимого и делителя) Сообщить() для чисел с большим числом знаков после десятичной точки - округляет, для больших по модулю чисел - выводит некорректно. и примерчик: //************* Процедура показать(знач а,знач р=0) стр=""; знак=""; Если а<0 Тогда знак="-"; а=-а; КонецЕсли; пока а<>Цел(а) цикл р=р+1; а=а*10; конеццикла; Пока а>0 цикл к=цел(а/10); м=(а-к*10); // м=а%10;а=(а-м)/10 - искажает результат (процент с большими числами не очень хорошо работает). а=к; стр=""+м+стр; р=р-1; Если р=0 Тогда стр="."+стр; КонецЕсли; КонецЦикла; Если р=0 тогда стр="0"+стр; КонецЕсли; стр=Знак+стр; симвВСтроке=150; Пока стрдлина(стр)>0 цикл сообщить(лев(стр,симвВСтроке)); Если стрдлина(стр)>симвВстроке Тогда стр=сред(стр,симвВСтроке+1,стрдлина(стр)-симвВСтроке) иначе стр=""; КонецЕсли; КонецЦикла; // сообщить(стр); // такая конструкция при большом количестве знаков выдает ошибку. КонецПроцедуры Функция абс(а) возврат ?(а<0,-а,а); КонецФункции Процедура корень(знач а,точность=100) х=0; хнов=1; р=0; пока (р<(точность+3)) цикл хнов=хнов*10; а=а*100; р=р+1; конеццикла; пока (абс(хнов-х)>2) цикл х=цел(хнов); // иначе на каждой итерации добавляется один разряд хнов=((а/х)+х)/2; //х=хнов; //хнов=цел(((а/х)+х)/2); сообщить("х ="); показать(хнов,р); сообщить("---------------"); сообщить("х*х ="); показать(хнов*хнов,2*р); сообщить("=========================="); конеццикла; КонецПроцедуры Процедура Сформировать() а=10; для в=1 по 12 цикл а=а*а; показать(а); сообщить("1С "); сообщить(а); сообщить("------------------------"); конеццикла; а=1.1; Для в=1 по 12 цикл а=а*а; показать(а); сообщить("--- после а/1"); показать(а/1); сообщить("1С "); сообщить(а); сообщить("------"); а=а-цел(а)+1; КонецЦикла; сообщить("на последок корень из двух"); корень(2,1000); КонецПроцедуры |
|||
29
aqua80
27.06.05
✎
15:42
|
to NS. Мне всегда казалось, что все языки программирования делятся по категориям. И 1С относится к проблеммно - ориентированным языкам. Так зачем прикручивать колеса к подводной лодке?
|
|||
30
NS
27.06.05
✎
16:52
|
(29) какие-такие колеса? Я ничего не прикручиваю.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |