What is Maximum Decimal Value using RS Logix 500 for a Long Integer Data File? - long-integer

Using RS Logix 500, what is the maximum decimal value for a Long Integer Data File?
I know the 32nd bit determines a negative or positive value.

Did the math myself, I should quit being so lazy.
2,147,483,647

Related

VBA Modulo Operation on large decimal numbers [duplicate]

This question already has answers here:
handling big number in vba
(2 answers)
Closed last month.
i am trying to calculate: A random number in the range 10^25 mod a random number in the range of 100.
I saved the first random number as a Variant because the number is too big to be saved as an Integer.
The result of the solution should be something between 1 and 100, so it could be saved as an Integer.
My idea is to break down the numbers into smaller numbers (prim factorisation) and calculate the modulo on smaller numbers, so we don't need to calculate in the range of 10^25.
For example calculation:
300400000717120000131495 mod 97 = 1
How to calc this by using VBA.
Thank you in advance.
Fabian
Does this work for you?
Sub test_this()
Debug.Print find_modulus("300400000717120000131495", 97)
End Sub
Function find_modulus(large_number As String, divisor As Long)
Dim quotient As Variant, integer_quotient As Variant
quotient = CDec(large_number)
integer_quotient = Int(quotient / divisor) * divisor
find_modulus = quotient - integer_quotient
End Function
(Variable names changed to make more sense.)

Basic VBA Questions (Integer)

Sub CommandButton1_Click()
Dim x As Integer
x = 6
Range("A1").Value = x
End Sub
This means that you assign X as Integer, and you say the x equals to 6.
And then you put the value x(=6) in cell "A1".
Sub CommandButton1_Click()
Dim x As Double
x = 6
Range("A1").Value = x
End Sub
But why does the second one work also?
TL;DR: Type conversions.
Range.Value is a Variant, which is a special data type that stores a pointer to a value, along with a description of the data type: that's how a cell can hold a Double, a String, a Boolean, or an Error value.
Anything deeper than that is irrelevant to the question at hand.
Integer is a 16-bit signed integer type that can easily fit into a Double, which is much larger than 16 bits. If you followed the .Value assignment with this:
Debug.Print TypeName(Range("A1").Value)
You would get Double in the debug output.
Somewhere in the implementation of the Range.Value property, a validation of the supplied value is performed, and if the value is acceptable, it's stored internally in the appropriate data type. If the value isn't of an acceptable data type, error 1004 is thrown. Integer being a fine numeric value, all is good.
The exact same thing happens in the second snippet: Double being a fine numeric value, all is good. And since any numeric value taken from a cell is a Variant/Double, we can reasonably infer that somewhere in the internal guts of Range, numeric values are stored as Double - although, that could very well just be an implementation detail of how the getter of the Range.Value property is implemented.
VBA was designed to work with a specific set of data types, and the type libraries of VBA host applications (e.g. Excel) were designed to accept these data types. Hence, you would have to work pretty hard to give Range.Value a value it can't deal with, using VBA code.
But before the value even gets to the Range.Value property, an implicit type conversion has aready occurred in the second snippet.
Dim x As Integer
x = 6
Here 6 is an integer literal. When VBA executes the x = 6 instruction, that 6 already has a data type - and that data type is Integer.
Dim x As Double
x = 6
Here 6 is also an integer literal, but it's assigned to a Double, which isn't the same type: an implicit type conversion occurs, and x happily takes an Integer value - because the conversion is widening.
Now consider:
Dim x As Double
x = 6#
Here 6# uses a type hint. Debug.Print TypeName(6#) prints Double: that 6# is a Double literal - no type conversion occurs here. But it's ugly.
Dim x As Double
x = CDbl(6)
Now the widening type conversion is explicit.
When an implicit conversion is narrowing instead, and the value can't fit into the needed data type...
Dim x As Integer
x = 32768 '<~ that's a Long integer literal: doesn't fit the 16 bits of an Integer
...then runtime error 6 ("Overflow") is thrown. Since every VBA numeric data type can safely be converted to a Double, every numeric value that can be supplied by VBA code, can be assigned to Range.Value.
Internally Excel does not use an Integer. Cells are one of four types:
Double precision floating point (all numbers including integers,
currency, dates times etc)
String
Boolean
Error
Note this means all numbers are doubles.
See these references:
Data types used by Excel - "All worksheet numbers in Excel are stored as doubles"
Excel VBA internal data format and memory storage

Lookup table for counting number of set bits in an Integer

Was trying to solve this popular interview question - http://www.careercup.com/question?id=3406682
There are 2 approaches to this that i was able to grasp -
Brian Kernighan's algo -
Bits counting algorithm (Brian Kernighan) in an integer time complexity
Lookup table.
I assume when people say use a lookup table, they mean a Hashmap with the Integer as key, and the count of number of set bits as value.
How does one construct this lookup table? Do we use Brian's algo to to count the number of bits the first time we encounter an integer, put it in hashtable, and next time we encounter that integer, retrieve value from hashtable?
PS: I am aware of the hardware and software api's available to perform popcount (Integer.bitCount()), but in context of this interview question, we are not allowed to use those methods.
I was looking for Answer everywhere but could not get the satisfactory explanation.
Let's start by understanding the concept of left shifting. When we shift a number left we multiply the number by 2 and shifting right will divide it by 2.
For example, if we want to generate number 20(binary 10100) from number 10(01010) then we have to shift number 10 to the left by one. we can see number of set bit in 10 and 20 is same except for the fact that bits in 20 is shifted one position to the left in comparison to number 10. so from here we can conclude that number of set bits in the number n is same as that of number of set bit in n/2(if n is even).
In case of odd numbers, like 21(10101) all bits will be same as number 20 except for the last bit, which will be set to 1 in case of 21 resulting in extra one set bit for odd number.
let's generalize this formual
number of set bits in n is number of set bits in n/2 if n is even
number of set bits in n is number of set bit in n/2 + 1 if n is odd (as in case of odd number last bit is set.
More generic Formula would be:
BitsSetTable256[i] = (i & 1) + BitsSetTable256[i / 2];
where BitsetTable256 is table we are building for bit count. For base case we can set BitsetTable256[0] = 0; rest of the table can be computed using above formula in bottom up approach.
Integers can directly be used to index arrays;
e.g. so you have just a simple array of unsigned 8bit integers containing the set-bit-count for 0x0001, 0x0002, 0x0003... and do a look up by array[number_to_test].
You don't need to implement a hash function to map an 16 bit integer to something that you can order so you can have a look up function!
To answer your question about how to compute this table:
int table[256]; /* For 8 bit lookup */
for (int i=0; i<256; i++) {
table[i] = table[i/2] + (i&1);
}
Lookup this table on every byte of the given integer and sum the values obtained.

Conversion from hexadecimal string to Double yields wrong results

I am trying to convert 14 bit hex numbers to decimal.
I have this VBA code.
Option Explicit
Public Function HexadecimalToDecimal(HexValue As String) As Double
Dim ModifiedHexValue As String
ModifiedHexValue = Replace(HexValue, "0x", "&H")
HexadecimalToDecimal = CDec(ModifiedHexValue)
End Function
With numbers like this to convert to decimal
0x047B1142591E80
0x044A81325A1E80
0x047B7542591E80
I keep getting random results across large amounts of data. Sometimes spot on other times the numbers are off by 6 or 2.
Try changing the return type of the function from Double to Variant. Double has only about 15 decimal digits of precision, so can't, for example, capture the value 1261213964639872 (which has 16 digits) exactly. The closest it can get is 1261213964639870. By changing the return type to Variant, the full precision returned by CDec will be preserved. You can't use a Decimal return type, because VBA for some reason does not support this.
The problem isn't with VBA. Excel cells can only hold 15 digits in number format. So the "number" 1234567891234567 will always display 1234567891234560. This can be avoided by converting items to text AND/OR changing the cell format to text.
But this doesn't always work.
The only surefire way to make sure it will retain all digits is to append something onto the string that isn't a number.
This code will append an apostrophe before the number, but return the entire string.
Public Function HexadecimalToDecimal(HexValue As String) As String
Dim ModifiedHexValue As String
ModifiedHexValue = Replace(HexValue, "0x", "&H")
HexadecimalToDecimal = "'" & CDec(ModifiedHexValue)
End Function
Unfortunately, not a perfect solution.

Conversion of numeric to string in MATLAB

Suppose I want to conver the number 0.011124325465476454 to string in MATLAB.
If I hit
mat2str(0.011124325465476454,100)
I get 0.011124325465476453 which differs in the last digit.
If I hit num2str(0.011124325465476454,'%5.25f')
I get 0.0111243254654764530000000
which is padded with undesirable zeros and differs in the last digit (3 should be 4).
I need a way to convert numerics with random number of decimals to their EXACT string matches (no zeros padded, no final digit modification).
Is there such as way?
EDIT: Since I din't have in mind the info about precision that Amro and nrz provided, I am adding some more additional info about the problem. The numbers I actually need to convert come from a C++ program that outputs them to a txt file and they are all of the C++ double type. [NOTE: The part that inputs the numbers from the txt file to MATLAB is not coded by me and I'm actually not allowed to modify it to keep the numbers as strings without converting them to numerics. I only have access to this code's "output" which is the numerics I'd like to convert]. So far I haven't gotten numbers with more than 17 decimals (NOTE: consequently the example provided above, with 18 decimals, is not very indicative).
Now, if the number has 15 digits eg 0.280783055069002
then num2str(0.280783055069002,'%5.17f') or mat2str(0.280783055069002,17) returns
0.28078305506900197
which is not the exact number (see last digits).
But if I hit mat2str(0.280783055069002,15) I get
0.280783055069002 which is correct!!!
Probably there a million ways to "code around" the problem (eg create a routine that does the conversion), but isn't there some way using the standard built-in MATLAB's to get desirable results when I input a number with random number of decimals (but no more than 17);
My HPF toolbox also allows you to work with an arbitrary precision of numbers in MATLAB.
In MATLAB, try this:
>> format long g
>> x = 0.280783054
x =
0.280783054
As you can see, MATLAB writes it out with the digits you have posed. But how does MATLAB really "feel" about that number? What does it store internally? See what sprintf says:
>> sprintf('%.60f',x)
ans =
0.280783053999999976380053112734458409249782562255859375000000
And this is what HPF sees, when it tries to extract that number from the double:
>> hpf(x,60)
ans =
0.280783053999999976380053112734458409249782562255859375000000
The fact is, almost all decimal numbers are NOT representable exactly in floating point arithmetic as a double. (0.5 or 0.375 are exceptions to that rule, for obvious reasons.)
However, when stored in a decimal form with 18 digits, we see that HPF did not need to store the number as a binary approximation to the decimal form.
x = hpf('0.280783054',[18 0])
x =
0.280783054
>> x.mantissa
ans =
2 8 0 7 8 3 0 5 4 0 0 0 0 0 0 0 0 0
What niels does not appreciate is that decimal numbers are not stored in decimal form as a double. For example what does 0.1 look like internally?
>> sprintf('%.60f',0.1)
ans =
0.100000000000000005551115123125782702118158340454101562500000
As you see, matlab does not store it as 0.1. In fact, matlab stores 0.1 as a binary number, here in effect...
1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + 1/65536 + ...
or if you prefer
2^-4 + 2^-5 + 2^-8 + 2^-9 + 2^-12 + 2^13 + 2^-16 + ...
To represent 0.1 exactly, this would take infinitely many such terms since 0.1 is a repeating number in binary. MATLAB stops at 52 bits. Just like 2/3 = 0.6666666666... as a decimal, 0.1 is stored only as an approximation as a double.
This is why your problem really is completely about precision and the binary form that a double comprises.
As a final edit after chat...
The point is that MATLAB uses a double to represent a number. So it will take in a number with up to 15 decimal digits and be able to spew them out with the proper format setting.
>> format long g
>> eps
ans =
2.22044604925031e-16
So for example...
>> x = 1.23456789012345
x =
1.23456789012345
And we see that MATLAB has gotten it right. But now add one more digit to the end.
>> x = 1.234567890123456
x =
1.23456789012346
In its full glory, look at x, as MATLAB sees it:
>> sprintf('%.60f',x)
ans =
1.234567890123456024298320699017494916915893554687500000000000
So always beware the last digit of any floating point number. MATLAB will try to round things intelligently, but 15 digits is just on the edge of where you are safe.
Is it necessary to use a tool like HPF or MP to solve such a problem? No, as long as you recognize the limitations of a double. However tools that offer arbitrary precision give you the ability to be more flexible when you need it. For example, HPF offers the use and control of guard digits down in that basement area. If you need them, they are there to save the digits you need from corruption.
You can use Multiple Precision Toolkit from MATLAB File Exchange for arbitrary precision numbers. Floating point numbers do not usually have a precise base-10 presentation.
That's because your number is beyond the precision of the double numeric type (it gives you between 15 to 17 significant decimal digits). In your case, it is rounded to the nearest representable number as soon as the literal is evaluated.
If you need more precision than what the double-precision floating-points provides, store the numbers in strings, or use arbitrary-precision libraries. For example use the Symbolic Toolbox:
sym('0.0111243254654764549999999')
You cannot get EXACT string since the number is stored in double type, or even long double type.
The number stored will be a subtle more or less than the number you gives.
computer only knows binary number 0 & 1. You must know that numbers in one radix may not expressed the same in other radix. For example, number 1/3, radix 10 yields 0.33333333...(The ellipsis (three dots) indicate that there would still be more digits to come, here is digit 3), and it will be truncated to 0.333333; radix 3 yields 0.10000000, see, no more or less, exactly the amount; radix 2 yields 0.01010101... , so it will likely truncated to 0.01010101 in computer,that's 85/256, less than 1/3 by rounding, and next time you fetch the number, it won't be the same you want.
So from the beginning, you should store the number in string instead of float type, otherwise it will lose precision.
Considering the precision problem, MATLAB provides symbolic computation to arbitrary precision.

Resources