Regex for floating point? - ruby

I'm trying to write a RegEx to validate a floating point number. Here's what I've managed thus far:
/^[-+]?[1-9]\d{0,2}(\.\d{1,1})?/
The number is valid if:
Either positive or negative
Max of 2 digits (tens or hundreds)
Hundredths digit can't 0 (only 1-9)
Scale is max of 1
Decimal value can be 0 or 5 or none at all
So these numbers would be valid, for ex:
1.5
-1.5
17.5
15
-3
30.5
These numbers would be invalid, for ex:
1.57
3041.5
17.59
915
-1.56
05.0

How about Float(number) (catch exceptions to detect parse errors) and then verify the floating point number? This will be easier for several of the properties than writing a regex. If you need to force a subset of the syntax accepted by Ruby to be used (why?), check only that part with a regex.

As I said in the comments - your first non-zero digit will count, then you add two more - which will now allow three-digit numbers like 915. To solve this the regexp way (with your testcases):
^[+-]?(?:(?!0)\d{1,2}|0)(?:\.[05])?$
I use negative lookahead (?!0) to make sure the first digit is not a zero, then just require the desired number of digits. It also allows 0.5 and similar through the |0 disjunction. If you prefer .5, it'll be this:
^[+-]?(?!0)\d{,2}(?:\.[05])?$
If you want to disallow 3.0 (allowed by your rules) and only allow 3 (as you imply in the examples), replace the last part:
^[+-]?(?:(?!0)\d{1,2}|0)(?:\.5)?$
However, this is much less readable than #Arkku's nice Float(number); use regexps if you really need them.

Here's a whole webpage on validating floats in regular expressions: http://www.regular-expressions.info/floatingpoint.html
That said,
{1,1} is equivalent to {1} which is equivalent to not putting it at all, so you can remove it
If you want to make sure that 0.5xyz doesn't pass, then add a $ at the end
With the above changes, it'd look like this: /^[-+]?[1-9]\d{0,2}(\.\d)?$/

According to your valid and invalid examples on: Regex for floating point?
This regex would work:
^[+-]?([1-9][0-9]?|0)(\.[05])?$

/^[-+]?\d{0,2}(\.[05])?(?!\d)$/
Matches when:
Value is either positive or negative
magnitude is less than 100. in the range of (-99.5 to 99.5)
Decimal value is .0 or .5 or absent (in other words, .0 or .5, or missing)
So these numbers would be valid, for ex:
1.5
-1.5
17.5
15
-3
30.5
-10.0
99.5
These numbers would be invalid, for ex:
1.57
3041.5
17.59
915
-1.56
05.0
99.6

Related

How do I use string formatter to restrain two digits before decimal point and two digits after in Ruby?

I'm well aware that if you want to force two digits, you do
"%2d" % blah
And if in a scenario that it is necessary to enforce two digits after decimal point, you do
".2f" % blah
I'm a bit confused on what should I do in order to combine those two together? Which is to say, 4.6 will be rendered as 04.60, and 34.274 will still be rendered as 34.27.
Apparently
"%2d.2f" % blah
doesn't work.
I'm thinking that I should probably go for
"%2d%.2f" % [bla_first_half, blah_second_half]
but I'm kind of reluctant to do so since it's a bit tedious.
I know if Java one can easily do
"##.##"
So is there any ruby counterpart like that? Cheers!
"%05.2f" % 4.66 # => 04.66
"%05.2f" % 34.274 # => 34.27
.2f means the float will be rounded to only two digits after the .
05 means the string will be no less than 5 characters and if there are less - it will fill the missing ones with 0.

Why is lua's string pattern matching doing this?

I have an external application which monitors CPU and GPU temperatures...
I am using Lua with the alien extension to grab these values (via GetWindowText) and to do some pattern matching on these values, effectively extracting the temperature digits out of the string, which by default shows up as something like CPU 67.875 °C...
But perhaps I have the wrong idea on how patterns work in LUA (since they don't appear to be exactly like regex)?
The pattern I am using is [%d]+[.%d+]* which should match any number between 0 and 100.0, correct?
Yet oddly enough, I am getting incredibly strange output when values reach around 56.5 degrees (see link).
Why is this happening?
And how can I extract the correct floating point values (as a string) between 0 and 100 in the format of XYY.ZZZ, where X is not optional, Y is optional, and . is optional unless Z exists?
You're seeing the effect of accumulated rounding errors because 0.16 cannot be precisely represented in floating point. The code below performs better:
local n = 0
while n < 10000 do
local s = tostring(n/100)
local t = s:match("[%d]+[.%d+]*")
print(t)
n = n + 16
end
Now, to your question, try the simpler pattern below:
s="CPU 67.875 °C"
print(s:match("CPU +(.-) +"))

Why does Round[2.75,0.1] return 2.800000000003?

Mathematica 8.0.1
Any one could explain what would be the logic behind this result
In[24]:= Round[10.75, .1]
Out[24]= 10.8
In[29]:= Round[2.75, .1]
Out[29]= 2.8000000000000003
I have expected the second result above to be 2.8?
EDIT 1:
I was trying to do the above for formatting purposes only to make the number fit in the space. I ended up doing the following to get the result I want:
In[41]:= NumberForm[2.75,2]
Out[41] 2.8
I wish Mathematica has printf() like formatting function. I find formatting numbers in Mathematica for exact field width and form a little awkward compared to using printf() formatting rules.
EDIT 2:
I tried $MaxExtraPrecision=1000 on some number I was trying for format/round, but it did not work, that is why I posted this question. Here it is
In[42]:= $MaxExtraPrecision=1000;
Round[2035.7520395261859,.1]
Out[43]= 2035.8000000000002
In[46]:= $MaxExtraPrecision=50;
Round[2.75,.1]
Out[47]= 2.8000000000000003
EDIT 3:
I found this way, to format a number to one decimal point only. Use Numberform, but first need to find what n-digit precision to use by counting the number of digits to the left of the decimal point, then adding 1.
In[56]:= x=2035.7520395261859;
NumberForm[x,IntegerLength[Round#x]+1]
Out[57]//NumberForm= 2035.8
EDIT 4:
The above (Edit 3) did not work for numbers such as
a=2.67301785 10^7
After some trials, I found Accounting Form to do what I want. AccountingForm gets rid of the 10^n form which NumberForm did not:
In[76]:= x=2035.7520395261859;
AccountingForm[x,IntegerLength[Round#x]+1]
Out[77]//AccountingForm= 2035.8
In[78]:= x=2.67301785 10^7;
AccountingForm[x,IntegerLength[Round#x]+1]
Out[79]//AccountingForm= 26730178.5
For formatting numerical values, the best language I found was Fortran, followed COBOL and also by those languages that use or support printf() standard formatting. With Mathematica, one can do such formatting I am sure, but it sure seems too complicated to me. I never understood why Mathematics does not have Printf[].
Not all decimal (base 10) numbers with a finite number of digits are representable in binary (base 2) with a finite number of digits. E.g. 0.1 is not representable in binary, just like 1/3 ~= 0.33333... is not representable in decimal. Mathematica (and other software) will only use a limited number of decimal digits when showing the number to hide this effect. However, occasionally it might happen that enough decimal digits are shown that the mismatch becomes visible.
http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding
EDIT
This command will show you what happens when you find the closes binary representation of 0.1 using 20 binary digits, then convert it back to decimal:
RealDigits[FromDigits[RealDigits[1/10, 2, 20], 2], 10]
The number is stored in base 2, rather than base 10 (decimal). It's impossible to represent 2.8 in base 2, so it uses the closest value: 2.8000000000000003
Number/AccountingForm can take a list in the second argument, the second item of which is how many digits after the decimal place to show:
In[61]:= x=2035.7520395261859;
In[62]:= AccountingForm[x,{Infinity,3}]
Out[62]//AccountingForm= 2035.752
Perhaps this is useful.

What methods can I use to analyse and guess 4-bit checksum algorithm?

[Background Story]
I am working with a 5 year old user identification system, and I am trying to add IDs to the database. The problem I have is that the system that reads the ID numbers requires some sort of checksum, and no-one working here now has ever worked with it, so no-one knows how it works.
I have access to the list of existing IDs, which already have correct checksums. Also, as the checksum only has 16 possible values, I can create any ID I want and run it through the authentication system up to 16 times until I get the correct checksum (but this is quite time consuming)
[Question]
What methods can I use to help guess the checksum algorithm of used for some data?
I have tried a few simple methods such as XORing and summing, but these have not worked.
So my question is: if I have data (in hexadecimal) like this:
data checksum
00029921 1
00013481 B
00026001 3
00004541 8
What methods can I use work out what sort of checksum is used?
i.e. should I try sequential numbers such as 00029921,00029922,00029923,... or 00029911,00029921,00029931,... If I do this what patterns should I look for in the changing checksum?
Similarly, would comparing swapped digits tell me anything useful about the checksum?
i.e. 00013481 and 00031481
Is there anything else that could tell me something useful? What about inverting one bit, or maybe one hex digit?
I am assuming that this will be a common checksum algorithm, but I don't know where to start in testing it.
I have read the following links, but I am not sure if I can apply any of this to my case, as I don't think mine is a CRC.
stackoverflow.com/questions/149617/how-could-i-guess-a-checksum-algorithm
stackoverflow.com/questions/2896753/find-the-algorithm-that-generates-the-checksum
cosc.canterbury.ac.nz/greg.ewing/essays/CRC-Reverse-Engineering.html
[ANSWER]
I have now downloaded a much larger list of data, and it turned out to be simpler than I was expecting, but for completeness, here is what I did.
data:
00024901 A
00024911 B
00024921 C
00024931 D
00042811 A
00042871 0
00042881 1
00042891 2
00042901 A
00042921 C
00042961 0
00042971 1
00042981 2
00043021 4
00043031 5
00043041 6
00043051 7
00043061 8
00043071 9
00043081 A
00043101 3
00043111 4
00043121 5
00043141 7
00043151 8
00043161 9
00043171 A
00044291 E
From these, I could see that when just one value was increased by a value, the checksum was also increased by the same value as in:
00024901 A
00024911 B
Also, two digits swapped did not change the checksum:
00024901 A
00042901 A
This means that the polynomial value (for these two positions at least) must be the same
Finally, the checksum for 00000000 was A, so I calculated the sum of digits plus A mod 16:
( (Σxi) +0xA )mod16
And this matched for all the values I had. Just to check that there was nothing sneaky going on with the first 3 digits that never changed in my data, I made up and tested some numbers as Eric suggested, and those all worked with this too!
Many checksums I've seen use simple weighted values based on the position of the digits. For example, if the weights are 3,5,7 the checksum might be 3*c[0] + 5*c[1] + 7*c[2], then mod 10 for the result. (In your case, mod 16, since you have 4 bit checksum)
To check if this might be the case, I suggest that you feed some simple values into your system to get an answer:
1000000 = ?
0100000 = ?
0010000 = ?
... etc. If there are simple weights based on position, this may reveal it. Even if the algorithm is something different, feeding in nice, simple values and looking for patterns may be enlightening. As Matti suggested, you/we will likely need to see more samples before decoding the pattern.

How to do high precision float point arithmetics in mathematica

In Mma, for example, I want to calculate
1.0492843824838929890231*0.2323432432432432^3
But it does not show the full precision. I tried N or various other functions but none seemed to work. How to achieve this? Many thanks.
When you specify numbers using decimal point, it takes them to have MachinePrecision, roughly 16 digits, hence the results typically have less than 16 meaningful digits. You can do infinite precision by using rational/algebraic numbers. If you want finite precision that's better than default, specify your numbers like this
123.23`100
This makes Mathematica interpret the number as having 100 digits of precision. So you can do
ans=1.0492843824838929890231`100*0.2323432432432432`100^3
Check precision of the final answer using Precision
Precision[ans]
Check tutorial/ArbitraryPrecisionNumbers for more details
You may do:
r[x_]:=Rationalize[x,0];
n = r#1.0492843824838929890231 (r#0.2323432432432432)^3
Out:
228598965838025665886943284771018147212124/17369643723462006556253010609136949809542531
And now, for example
N[n,100]
0.01316083216659453615093767083090600540780118249299143245357391544869\
928014026433963352910151464006549
Sometimes you just want to see more of the machine precision result. These are a few methods.
(1) Put the cursor at the end of the output line, and press Enter (not on the numeric keypad) to copy the output to a new input line, showing all digits.
(2) Use InputForm as in InputForm[1.0/7]
(3) Change the setting of PrintPrecision using the Options Inspector.

Resources