4
« on: May 10, 2014, 11:25:39 AM »
Не смог найти полноценную функцию преобразования строк в числа (применительно к десятичным дробям). Если она есть, то может кто-нибудь подскажет?
А так как я её не нашёл, то реализовал скриптик такого преобразования на основе int (). Правда, получился не совсем скриптик, а некий исследовательский скрипт с кучей комментариев, из которых, я думаю, всё понятно. Поэтому здесь описывать не буду - смотрите скрипт и комментарии в нём. Проблема вылезла при попытке сравнения строки ввода с числами. Там оказалось довольно много для меня интересного. Не судите строго, для корифеев всё это, возможно, азбука. Но я недавно освоение кликера начал.
// Перевод строки в число
// Author: GHksd5sf3sQdewrj
// Version: 1.0 (10.05.2014)
#name "txt2num"
// Данный скрипт тестовый. Поводом к его написанию послужило то, что я не смог
// найти нормального способа преобразования строки, содержащей число в виде
// десятичной дроби в собственно число. Целые числа можно преобразовывать
// с помощью функции int (). Для десятичных дробей она не работает.
// Точнее, работает криво, заодно округляя число до целого.
// Скрипт пытается сравнивать введенное число (в текстовом виде) с 555.55
// Поэкспериментируйте с разыми числами и вы увидите, что результат сравнения
// зависит не от числа, а от количества символов в нём и ещё чего-то.
// Например, попробуйте ввести числа 675.1, 987.4, 338.567, 222.121 и т.п.
// При попытке сравнения чисел, содержащих столько же символов, сколько и
// тестовое число 555.55 (например, "1.2456", "236.22", "987445", "24.568")
// обнаружен дополнительный глюк. В блоке вывода есть комментарий.
// Реализован некий защитный функционал, анализирующий правильность ввода
// (собственно, я его не писал для решения этой простой задачи, а просто
// скопировал из другого скрипта). Некоторые символы в строке ввода
// принципиально не допустимы, например "/". При их наличии в результирующей
// переменной скрипт просто "вылетает" с ошибкой при попытке что-то сделать
// с этой переменной.
// Отрицательные числа я не рассматривал, введение "-" скрипт воспринимает, как
// ошибку. Мне они не нужны были. У кого нужда возникнет, думаю, допилит.
// Для остановки скрипта воспользуйтесь сочетанием клавиш Alt+S (по дефолту)
// или введите вместо числа слово "stop".
define ($a) // число, как строка
define ($b) // число, как число
define ($i)
define ($jj)
define ($pos) // позиция точки
define ($la)
define ($ra)
define ($r)
define ($SimbolFound)
define ($NumPoint)
For ($i, $i < 10)
$sim [$i] = $i // Что интересно, вроде числа по массиву разгоняю, а далее
// использую их для сравнения со строками. Вполне работает. Впрочем,
// далее будет видно, что простые сравнения чисел и строк вполне проходят.
// Возможно ещё оказывает какое-то влияние, что ниже 2 элемента массива
// строковые. Интересно, как кликер в теории относится к смешанным элементам в массиве?
End_cyc
$sim [10] = "."
$sim [11] = ","
LOGSHOW (1)
If (WNDFIND ("Clickermann - Лог") > 0)
WNDSIZE (WNDFIND ("Clickermann - Лог"), 720, 350)
End_if
print ("-------------------------------------------------------------")
Print ("Для остановки скрипта воспользуйтесь сочетанием клавиш Alt+S")
Print (" (по дефолту) или введите вместо числа слово stop.")
print ("")
print ("Скрипт пытается сравнивать введенное число (в текстовом виде) с 555.55")
print ("Поэкспериментируйте с разыми числами и вы увидите, что результат")
print ("сравнения зависит не от числа, а от количества символов в нём.")
print ("Например, попробуйте ввести числа 675.1, 987.4, 338.567, 222.121 и т.п.")
next:
$a = INPUTBOX("Введите десятичное число (предпочтительно с дробной частью). Для остановки скрипта введите слово stop.", "", 3600)
if (($a = "stop") | ($a = "стоп") | ($a = "STOP") | ($a = "Stop"))
halt
end_if
// ### Начало блока преобразователя строки $a в число $b ###
// - для вставки в другие скрипты. Тут же проверялка против неверного ввода.
$pos = 0
$NumPoint = 0
$SimbolFound = 0
for ($i = 1, $i < STRLEN ($a) + 1)
For ($jj, $jj < 12)
If (STRCUT ($a, $i, 1) = $sim [$jj])
$SimbolFound = 1
End_if
End_cyc
If ($SimbolFound = 0)
print ("")
print ("Введенное выражение содержит недопустимые символы!")
goto (next)
End_if
if ((STRCUT ($a, $i, 1) = ".") or (STRCUT ($a, $i, 1) = ","))
$NumPoint = $NumPoint + 1
$pos = $i
end_if
end_cyc
if ($NumPoint > 1)
print ("")
print ("Введенное выражение содержит более одной десятичной точки (запятой)!")
goto (next)
end_if
if ($pos = 0)
$pos = STRLEN ($a) + 1 // Для случая введения целого числа без точки
end_if
$la = STRCUT2 ($a, 1, $pos - 1) // целая часть числа (строка)
$ra = strcut2 ($a, $pos + 1, STRLEN ($a)) // дробная часть числа (строка)
$r = strlen ($a) - $pos // разрядность дроби (не верно для целого числа, но работает за счёт нулевой дробной части)
$b = int ($la) + int ($ra) / pow (10, $r) // Собираем число
// ### Конец блока преобразователя ###
// Блок вывода результатов
print ("")
// Прошу обратить внимание, что тут я сравниваю строковую переменную $a с числом.
// В $a содержится без изменений то, что Вы ввели в диалоговом окошке.
if ($a > 555.55)
print ("Ваше число ", $a, " больше 555.55 Верно?")
end_if
if ($a < 555.55)
print ("Ваше число ", $a, " меньше 555.55 Верно?")
end_if
// По результатам будет очевидно, что сравнение происходит по правилу сравнения строк -
// сравнивается длина строки $a с "длиной" числа 555.55
if ($a = 555.55)
print ("Ваше число ", $a, " равно 555.55 Верно?")
// А это условие на предмет равенства вообще прикольно работает :)
// Если число символов в строке $a совпадает с числом цифр (плюс точка),
// короче, с числом символов в числе 555.55, то условие равенства
// выполняется исключительно для строки "555.55". Таким образом,
// для строк типа "1.2456", "236.22", "987445", "24.568", "555,55" (с запятой) не выполняется
// ни одно из трёх условий выше и в лог не выводится ни одно из 3-х
// сообщений. Для этого случая выведем следующее:
end_if
if ((STRLEN ($a) = STRLEN ("555.55")) & ($a ! "555.55"))
print ("Исключительный случай. При длине строки равном числу символов")
print ("в числе 555.55 сравнение не проходит (кроме самого 555.55). См. комментарии")
end_if
if ($a = $b)
Print ("Строковое $a ", $a," вполне равно числому $b ", $b, ". Но бывают исключения.")
// Данный результат получается в большинстве стандартных ситуаций, например,
// для чисел 123.546, 555.55, 124.78, 1.2, 689, 1002, 7896.455,
// Но он не будет получен для очень больших чисел с дробной частью,
// например, 145689875324.234, при вводе пустой строки "" не равно 0,
// при вводе неправильных чисел, начинающихся или заканчивающихся точкой
// (запятой), например, .123 4567. 455. .1456 (может это и не правильно, но мой
// скрипт способен преобразовывать эти конструкции в целые числа и числа вида
// 0.ххх соответственно)
// Так же, когда число было введено через запятую - но это уже моё извращение
// исключительно ради удобства. Числа в Clickermann пишутся через точку (.).
// Для этих обнаруженных случаев (может есть и ещё) будет выдано сообщение ниже
else
Print ("Строковое $a ", $a," не равно числовому $b ", $b," (иногда появляется")
print ("В скрипте есть комментарий по обнаруженным случаям таких сообщений.")
End_if
goto (next)
halt // for single run