Данный плагин позволяет производит математические операции с числами с плавающей точкой.
Плагин необходимо поместить в папку Plugins рядом с uopilot.exe. Для работы требуются установленные библиотеки c++:
http://www.microsoft.com/ru-ru/download/details.aspx?id=40784
math.dbl (<var1> <sign> <var2>)
<var1> - первое число (может быть не целым).
<sign> - знак математической операции (+-/*).
<var2> - второе число (может быть не целым).
Корректной последовательностью чисел с плавающей точкой для считается последовательность, удовлетворяющая следующим условиям:
Знак положительного или отрицательного числа (необязательно).
Последовательность цифр, как вариант, может содержать десятичную точку или запятую.
Дополнительная экспонентная часть, которая сама по себе состоит из символа 'e' или 'E',
после которого следует дополнительный знак и последовательность цифр.
Диапазон значений:
min: 2,2250738585072014 E – 308
max: 1,7976931348623158 E + 308
Результат работы функции должен быть присвоен массиву. Возвращаемые значения:
%a [1] - результат математической операции. Если функция завершилась с ошибкой, вернет "0".
%a [2] - возвращает OK, если функция успешно выполнена, Error, если произошла ошибка.
%a [3] - расшифровка ошибки:
Succes - функция завершилась успешно. (%a [2]="OK")
First value: ERANGE - первый параметр за пределами допустимого значения.
Second value: ERANGE - второй параметр за пределами допустимого значения.
No sign: [символ] - знак математической операции не найден.
Пример:
set %a math.dbl (12.1 / 3)
log Результат вычислений: %a [1]
log Ошибка: %a [2]
log Текст ошибки: %a [3]
В плагин не следует передавать несколько математический операций, использовать скобки и т.д.
Функция должна принять только перечисленные выше параметры.
Если необходимо произвести какие-либо длинные математические вычисления,
то производите их до передачи параметров или используйте eval().
При работе с числами с плавающей точкой нужно понимать:
Расчет формулы «x2-y2» лучше вычислять используя формулу «(x-y)(x+y)».
В арифметике с плавающей запятой правило (a*b)*c = a*(b*c) не выполняется для любых арифметических операций.
Не все десятичные числа имеют двоичное представление с плавающей запятой. Например, число «9999999999.2» будет представлено как «9999999999.200001».
При сравнении чисел с плавающей точкой не корректно выражение:
a < b
Для подобного сравнения правильным будет сравнение разницы чисел с некоторой константой:
c = a - b
abs(c) < 0.1
0.1 взято для примера, точность вы можете задать самостоятельно.
Так же необходимо понимать, что использование чисел с плавающей точкой(в т.ч. их разницы) в пилоте
по средствам оператора if может быть не корректным.
set %a math.dbl (12.1 / 3)
Спасибо.
set %a math.dbl (1234,567 / 37)
log %a [1]
stop_script
set %b WindowStatus.find (1111 *UoPilot v2.35 WK* TfmMain) //поиск пилота (работает, тут нет проблем)
set %a math.dbl (1234,567 / 37)
log %a [1] //результат 0
stop_script
set %b WindowStatus.find (1111 *UoPilot v2.35 WK* TfmMain)
%TfmMain) [ 2 1 ] = 525014
set %a math.dbl (1234,567 / 37)
%37) [ 4 1 ] = No sign: .
log %a(0) [1]
0
stop_script
Надо тыкать кнайта. Что-то не так с областями видимости походу.
Проблема оказалась в изменении локали плагином для поиска окон. Локаль сохраняется и приводит к тому, что стандартная функция c++ перестает воспринимать точку, как десятичный разделитель, и требует запятую. Запятую можешь не ставить - они заменяются на точки при парсинге строки. В описании функции с++, которая начинает сыпаться явно указано "десятичная точка", т.е. по сути получается нарушение стандарта.
Так с точкой также результат 0.
Дык в том то и фишка, что он запятую требует после плагина с поиском окон. А запятая не пройдет, т.к. все запятые автоматически заменяются на точки для соответствия заявленным стандартам.
Так плагин с точкой тоже должен работать.
set %b WindowStatus.find (1111 *UoPilot v2.35 WK* TfmMain)
set %a math.dbl (1234.567 / 37) //тут нет запятых
log %a [1]
// Заменяем все запятые на точки.
for (unsigned char i = 0; ParamStruct->ParamString[i] != '\0'; i++){
if (ParamStruct->ParamString[i] == ','){
ParamStruct->ParamString[i] = '.';
}
}
char * pPos; // Указатель на последний символ разобранной строки +1 (вернет значение).
double firstVal = strtod(ParamStruct->ParamString, &pPos) // А вот тут будет ошибка;
Т.е. только перезагружать плагины?
set %b WindowStatus.find (1111 *UoPilot v2.36.1 WK* TfmMain)
pluginreload
set %a math.dbl (1234,567 / 37)
log %a [1]
Ну пока - да. Вообще могу под запятую быро скомпилить. Кнайт не вовремя свалил из аськи. Надо обсудить и понять, что с этим делать. Со своей стороны я могу и локаль принудительно менять под нужную и попробовать изменить плагин поиска окна. Т.е. решить проблему можно и на моей стороне без особых трудозатрат. Просто надо понять, как это сделать наиболее корректно.
Есть в 2019 году способ умножения десятичных чисел?
а чо когда выполняю такой код
set %arr [1 13] 8
set %op [1 2] math.dbl (%arr [1 13] * 2.25)
log %op [1 2]
end_script
В первом посте пример есть:
set %a math.dbl (12.1 / 3)
log Результат вычислений: %a [1]
end_script
set %a math.dbl (12.1 / 3)
log Результат вычислений: %a [1]
end_script
set %a math.dbl (8 * 2.26)
log clear
log mode compact
log Результат вычислений: %a [1]
set $temp %a [1]
set $a trunc($temp)
set $b frac($temp)
while 1 = 1
set $temp copy($b size($b) 1)
if $temp = 0
set $b Delete($b size($b) 1)
else
break
end_if
end_while
set %a[1] $a
if $b != ""
set %a [1 2] ","
set %a [1 3] $b
end_if
log %a [1]
end_script
set #f 3 // здесь задать кол-во знаков после запятой
set %a math.dbl (12.1 / 3)
set $a %a[1]
set $a copy($a 1 eval(posex("," $a)+#f))
log $a
end_script
Оставит после зяпятой нужное количество знаков, или вернёт целое число.
set #f 3 // здесь задать кол-во знаков после запятой
set %a math.dbl (10 / 5)
set $a %a[1]
if frac($a) > 0
set $a copy($a 1 eval(posex("," $a)+#f))
else
set $a trunc($a)
end_if
log $a
end_script
Пример
59,4/11+2,3*2
set %a math.dbl (59.4 / 11)
call r %a[1]
set $a $r
set %b math.dbl (2.3 * 2)
call r %b[1]
set $b $r
set %c math.dbl ($a + $b)
call r %c[1]
set $c $r
log $c
end_script
proc r $x
set linedelay 1
set #f 3
if frac($x) > 0
set $result copy($x 1 eval(posex("," $x)+#f))
else
set $result trunc($x)
end_if
end_proc
3,000000 = 3
3,007000 = 3,007
3,373000 = 3,373
3,333333 = 3,333333
set $a math.dbl (59.4 / 11)
call m $a
set $a $m
set $b math.dbl (2.202 * 2)
call m $b
set $b $m
set $c math.dbl ($a + $b)
call m $c
set $c $m
log $c
end_script
proc m $x
set #n regexp (#p $result $x (\d+?(?=,0+\b)|\d+[,.]\d+?(?=0+\b)|\d+[,.]\d+))
end_proc
Ну наконец-то я придумал как это провернуть)
Итак, для всех, кто мечтал об операциях с дробными числами в одну строку кода, как например:
call m $a 59.4 / 11
call m $b 2.202 * 2
call m $c $a + $b
log Ответ: $c
end_script
call m $a 59.4 / 11
call m "$a" 2.202 * 2
log Ответ: $a
end_script
"...плакали, кололись, но продолжали грызть кактус."
Fors1k, не нужно воспринимать это так в штыки. Вы можете использовать любые языки, вам никто не запрещает и имелось ввиду совсем иное. Lua был встроен чтобы решить очень многие проблемы пилота в части скриптового движка - они были при этом решены. Вы по своим соображениям выбираете старый синтаксис, который не содержит этих решений. Это ваше право и никто его не отбирает, но со стороны возникают логичные вопросы о целесообразности данных действий и вам намекают, что возможно стоит перестать хвататься за старое, но столь привычное. Есть некоторые старые очень объемные вещи и у меня, которые я не готов переводить на луа, но каждый раз, когда нужно что-то там править для меня это целая беда . Присмотритесь, возможно пришло время и не более того.
call m $a 5.409 * 2.7
log $a
call m $if $a > 10.25
if $if
log Yes
else
log No
end_if
end_script
Добавил возможность через switch сделать ветвление по условиям > ; < ; =.
......................................................
call m $var <arg1> ? <arg2>
......................................................
При повторном/многократном сравнении через одну и ту же переменную($sw) следует использовать запись: call m "$var" <arg1> ? <arg2> .
Пример.
Допустим, нам нужно скопирвать число, и сделать одно из трех действий, в зависимости от его отношения к другому числу.
double_kleft x y
get clipboard $a
call m $sw $a ? 114.58
switch $sw
case >
log arg1 больше
break
case <
log arg1 меньше
break
case =
log arg1 и arg2 равны
break
end_switch
End_script
Добавил условие неравенства.
При повторном/многократном сравнении через одну и ту же переменную($if) следует использовать запись: call m "$var" <arg1> <sign> <arg2> .
call m $a 5.505 * 2
log $a
call m $if $a != 11.01
if $if
log Yes
else
log No
end_if
end_script
ВАХ, спасибо БОЛЬШОЕ, Форсик.
трое суток учил Lua. = ото уж точно "продолжали грызть кактус"
список функций не полный. всё-равно костыль на костыле. не понятный скрипт в непонятном скрипте.
уже даже задумывался передавать через пилот в SQL, от туда считать через php.
и даже не думал что решится так просто.
U MAKE MY DAY.
позволь угостить тебя хорошим чаем. скинь реквы в личку.
<3
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)