Имя: Пароль:
LIFE
 
ОФФ встроенный язык 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) какие-такие колеса? Я ничего не прикручиваю.
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший