Finding negative numbers in a field in ILog - business-rules

I have a following requirement in Ilog Jrules,
Having an Integer field that contains both positive and negative numbers.
Requirement is to loop through the Integer field, find and remove the negative sign in the negative numbers.
It sounds simple but I could n't find a way to to this.
Any help or pointers would be highly appreciated. Many thanks.

(Supposing that XArray is an input/output Array of Integer in your rule project)
You can create a rule like this:
definitions
set 'x' to a Number from XArray;
if
x is less than 0
then
set x to -x;
PS: don't forget to add the rule in a ruleTask (with RetePlus Alogorithm: default) in the main ruleflow.

I ve created the following function in BOM to XML mapping and passing all the incoming integer field values through this, which solved the problem.
if (integer < 0)
return integer * -1;
else
return integer;

Related

Airtable If-statement outputting NaN

I'm using an If-statement to assign integers to strings from another cell. This seems to be working, but if I reference these columns, I'm getting a NaN value. This is my formula below. I tried adding INT() around the output values, but that seemed to break everything. Am I missing something?
IF(FIND('1',{Functional response}),-4,
IF(FIND('2',{Functional response}),-2,
IF(FIND('3',{Functional response}),0,
IF(FIND('4',{Functional response}),2,
IF(FIND('5',{Functional response}),4,"")))))
Assuming Functional response can only store a number 1 to 5 as a string a simple option in excel would be to first convert the string to a number and then use the choose function to assign a value. this works as the numbers are are sequential integers. Assuming Cell K2 has the value of Functional response, your formula could be:
=CHOOSE(--K2,-4,-2,0,2,4)
=CHOOSE(K2+0,-4,-2,0,2,4)
=CHOOSE(K2-0,-4,-2,0,2,4)
=CHOOSE(K2*1,-4,-2,0,2,4)
=CHOOSE(K2/1,-4,-2,0,2,4)
Basically sending the string of a pure number through a math operation has excel convert it to a number. By sending it through a math operation that does not change its value, you get the string as a number.
CHOOSE is like a sequential IF function Supply it with an integer as the first argument and then it will return the value from the subsequent list that matches the number. if the number you supply is greater than the number of options you will get an error.
Alternatively you could just do a straight math convertion on the number stored as a string in K2 using the following formula:
=(K2-3)*2
And as my final option, you could build a table and use VLOOKUP or INDEX/MATCH.
NOTE: If B2:B6 was stored as strings instead of numbers, K2 instead of --K2 would need to be used.

Subtracting Numbers larger than 18 digits in length

Ok this is a tough one or else a stupid one but it has me stumped. I am working with serial numbers in MSSQL and they are stored in the database as nvarchar(50) and to do subtracting calculations on them I use the following query to convert them to the data-type BIGINT and subtract as normal.
SELECT
SUM(
CAST(second_Serial_Nb AS BIGINT)-CAST(Serial_Nb AS BIGINT))
FROM [TEST].[dbo].[Serial_Table]
WHERE ID = '3'
this query works fine for serial numbers up to 18 digits in length, but as soon as I increase there size of the serial numbers to 20 digits in length I get the error that the numbers can not be converted to data-type bigint
Msg 8815, Level 16, State 2, Line 2
Arithmetic overflow error converting expression to data type bigint
Is there a work around using a different number data type like hexi or something. I am also using C++ maybe I could create a function there instead of SQL?
Any comments or suggestions greatly appreciated, Thanks for reading.
BIGINT is just a normal, 64-bit integer. It is not an arbitrary-precision integer.
If you want to store more information, you can either keep it in string form, or use a NUMERIC or DECIMAL type; both solutions are of course much slower than a native, fixed-width integer.

Perl: Looping Through an Array to Increment the Values of a Hash

I am new to perl and I have a problem that I'm trying to solve. At this stage in my program, I have placed a file into an array and created a hash where all the keys are numbers, that increase by a user specified bin size, within a range The values of all keys are set to 0. My goal is to loop through the array and find numbers that match the keys of my hash, and increment the corresponding value by 1 in the event of a match. To make finding the specific value within the array a bit easier, each line of the array will only contain one number of interest, and this number will ALWAYS be a decimal, so maybe I can use the regex:
=~ m{(\d+\.\d+)}
to pick out the numbers of interest. After finding the number of interest, I need to round down the number (at the minute I an using "Math::Round 'nlowmult';") so that it can drop into the appropriate bin (if it exists), and if the bin does not exist, the loop needs to continue until all lines of the array have been scanned.
So the overall aim is to have a hash which has a record of the number of times that values in this array appear, within a user specified range and increment (bin size).
At the minute my code attempting this is (MathRound has been called earlier in the program):
my $msline;
foreach $msline (#msfile) {
chomp $msline;
my ($name, $pnum, $m2c, $charge, $missed, $sequence) = split (" ", $msline);
if ($m2c =~ /[$lowerbound,$upperbound]/) {
nlowmult ($binsize, $m2c);
$hash{$m2c}++;
}
}
NOTE: each line of the array contains 6 fields, with the number of interest always appearing in the third field "m2c".
The program isn't rounding the values down, neither is it adding values to the keys, it is making new keys and incrementing these. I also don't think using split is a good idea, since a real array will contain around 40,000 lines. This may make the hash population process really slow.
Where am I going wrong? Can anybody give me any tips as to how I can go about solving this problem? If any aspects of the problem needs explaining further, let me know!
Thank you in advance!
Change:
if ($m2c =~ /[$lowerbound,$upperbound]/) {
nlowmult ($binsize, $m2c);
$hash{$m2c}++;
}
to:
if ($m2c >= $lowerbound && $m2c <= $upperbound) {
$m2c = nlowmult ($binsize, $m2c);
$hash{$m2c}++;
}
You can't use a regular expression like that to test numeric ranges. And you're using the original value of $m2c as the hash key, not the rounded value.
I think the main problem is your line:
nlowmult ($binsize, $m2c);
Changing this line to:
$m2c = nlowmult ($binsize, $m2c);
would solve at least that problem, because nlowmult() doesn't actually modify $m2c. It just returns the rounded result. You need to tell perl to store that result back into $m2c.
You could combine that line and the one below it if you don't want to actually modify the contents of $m2c:
$hash{nlowmult ($binsize, $m2c)}++;
Probably not a compete answer, but I hope that helps.

Regex less than or greater than 0

I'm trying to find a regex that validates for a number being greater or less than 0.
It must allow a number to be 1.20, -2, 0.0000001, etc...it simply can't be 0 and it must be a number, also means it can't be 0.00, 0.0
^(?=.*[1-9])(?:[1-9]\d*\.?|0?\.)\d*$
tried that but it does not allows negative
I don't think a regex is the appropriate tool for that problem.
Why not using a simple condition ?
long number = ...;
if (number != 0)
{
// ...
}
Why using a bazooka to kill a fly ?
also tried something:
-?[0-9]*([1-9][0-9]*(\.[0-9]*)?|\.[0-9]*[1-9][0-9]*)
demo: http://regex101.com/r/bZ8fE5
Just tried something:
[+-]?(?:\d*[1-9]\d*(?:\.\d+)?|0+\.\d*[1-9]\d*)
Online demo
Take a typical regex for a number, say
^[+-]?[0-9]*(\.[0-9]*)?$
and then require that there be a non-zero digit either before or after the decimal. Based on your examples, you're not expecting leading zeros before the decimal, so a simple regex might be
^([+-]?[1-9][0-9]*(\.[0-9]*)?)|([+-]?[0-9]*\.0*[1-9]*0*)
Then decide if you still want to use a regex for this.
Try to negate the regex like this
!^[0\.]+$
If you're feeling the need to use regex just because it's stored as a String you could use Double.parseDouble() to covert the string into a numeric type. This would have an added advantage of checking if the string is a valid number or not (by catching NumberFormatException).

How to write a regular expression to validate a variable against 0-100 or an e

I would like to write a regular expression to validate and input field against the following arguments:
field is required (cannot be
empty)
field must not be a negative number
field must be a validate decimal
number to two decimals (eg. 1 or 1.3
or 1.23)
field can be any valid number between 0 and 100 or an 'e'
Regular expressions find great use in checking format, but you're wishing to use it to do a subset of floating point number parsing and bounds checking. Be kind to yourself and the person who will maintain your code after you're gone: check if it's an 'e', else read it into a float and check the bounds.
You can use: ^(100|\d{1,2}(\.\d{1,2})?|e)$
However, it would be simpler and more readable to use your language's float parsing/casting functions.
EDIT: Some variations based on the comments:
Allowing 100.0 and 100.00: ^(100(\.0{1,2})?|\d{1,2}(\.\d{1,2})?|e)$
Disallowing leading zeroes: ^(100(\.0{1,2})?|[1-9]?\d(\.\d{1,2})?|e)$
^(?:100|\d{1,2}(?:\.\d{1,2})?|e)$
Hmm does this work for you?
^((100|[0-9]{1,2})(\.[0-9]{1,2})?)|(e)$
Whay environment is this for? Any particular regex standard it must adhere to?
Constraints on numeric values (such as "> 100", or "<= 5.3") can make regexes rather complicated. These types of contraints are better checkedin application logic. Then you can have a simpler (and easier to understand) pattern:
^(([0-9]{1,3})(\.[0-9]{1,2})?)|(e)$
And then extract the capture group for the first 3 digits and validate that separately.
Edit:
Ok I think this one should do it (last one because my eyes are getting tired):
^(100(\.0{1,2})?)|([0-9]{1,2})(\.[0-9]{1,2})?|(e)$
Will also allow 100.00 or 100.0