Every time when i want to receive an element from vector (let's say, std_logic from std_logic_vector via std_logic_vector(index)), the index should be exactly an integer (i am using VHDL98 standard).
Could you explain please, why should the index be an integer (and not an unsigned, for example)?
I've googled all over the Internet, but no explanation was found :(
Thank you!
Related
Okay, so it may not be that strange, but I'm really new to Ada. In my job, I am translating legacy Ada to C, and have come across something that I haven't seen yet. I searched around, but couldn't really find it; here it is.
type Discrete_Names is ( ENUM_POS_4, --label names in an enum
ENUM_POS_5, --that evaluate to 4, 5, and 6
ENUM_POS_6); --respectively
type Discrete_Array_Type is Array (Discrete_Names) of Discrete.Does_Not_Matter
Side note—the Discrete.Does_Not_Matter just references another type in a different library.
It would be great if someone could just help me get my bearings and just figure out what is going on here.
Well, it is quite simple. In Ada arrays can be indexed by any discrete type, that is, integers, characters or enumeration types (your case). The line
type Discrete_Array_Type is Array (Discrete_Names) of Does_Not_Matter
declares Discrete_Array_Type as the type of an array that contains values of type Does_Not_Matter and it is indexed by values of type Discrete_Names.
If your doubt stems from the fact that ENUM_POS_4 has Pos equal to 4 -- so that it seems that the first index of the array is 4 and not 0 -- my suggestion is... forget about it. The compiler will take care of that. In Ada arrays can start from any index. For example, if you say
type Array_Foo is array(Positive range <>) of Characters;
Bar : Array_Foo(10..15);
Bar will be just 6 entries long (not 16) and when you access Bar(12) the compiler -- behind the scenes -- will remove the initial offset "10" to "12" so that you will access the third memory location reserved to Bar. (Actually, I think that for the sake of efficiency it will add 12 to the address of Bar diminished by 10 times the integer sizes, but this is a detail...)
My personal experience is that in cases like this you should not consider the enumerative type like a "integer in disguise" (although it will be internally represented by an integer), but like a type of its own that can be used to index an array. Let the compiler worry about the internal low-level details.
I have the current time in seconds like this:
The_Seconds : DAY_DURATION;
And I wish to convert it to an Integer. How can I do it?
Thank you.
What's the definition of DAY_DURATION?
If it's just in seconds it might be an integral type so Integer( The_Seconds ) would work; if it's a Float that syntax should also work, but you'll have to give some thought to whether to truncate, round, or ceiling it before conversion [look into the floating-point Attributes].
Day_Duration is a subtype of Duration, which is a fixed point type declared in package Standard.
Just type convert it.
In python the function math.log(1000, 10) returns
2.9999999998 or some approximate value (neraly every third integer does that)
Which firstly is kind of messed up even though I imagine there's not much (except divisibility tests) to do about it.
And secondly it's not the value I want of course, how should I proceed? Casting to int will clearly return 2 and not 3... So what method is used to get the round to nearest int? In this case and in general, please.
Someone removed his/her answer before I could accept it, so I write mine which is no more than a summary.
Two options that I liked:
In this particular case, since the operation was math.log(1000, 10), it could be replaced with math.log10(1000) which shows much greater precision.
In a more general case, round(math.log(1000, 10)) will round 2.999... to the integer 3 so this would be more what was asked.
my problem why my program takes much large time to execute, this program is supposed to check the user password, the approach used is
take password form console in to array and
compare it with previously saved password
comparision is done by function str_cmp()-returns zero if strings are equal,non zero if not equal
#include<stdio.h>
char str_cmp(char *,char *);
int main(void)
{
int i=0;
char c,cmp[10],org[10]="0123456789";
printf("\nEnter your account password\ntype 0123456789\n");
for(i=0;(c=getchar())!=EOF;i++)
cmp[i]=c;
if(!str_cmp(org,cmp))
{
printf("\nLogin Sucessful");
}
else
printf("\nIncorrect Password");
return 0;
}
char str_cmp(char *porg,char *pcmp)
{
int i=0,l=0;
for(i=0;*porg+i;i++)
{
if(!(*porg+i==*pcmp+i))
{
l++;
}
}
return l;
}
There are libraries available to do this much more simply but I will assume that this is an assignment and either way it is a good learning experience. I think the problem is in your for loop in the str_cmp function. The condition you are using is "*porg+i". This is not really doing a comparison. What the compiler is going to do is go until the expression is equal to 0. That will happen once i is so large that *porg+i is larger than what an "int" can store and it gets reset to 0 (this is called overflowing the variable).
Instead, you should pass a size into the str_cmp function corresponding to the length of the strings. In the for loop condition you should make sure that i < str_size.
However, there is a build in strncmp function (http://www.elook.org/programming/c/strncmp.html) that does this exact thing.
You also have a different problem. You are doing pointer addition like so:
*porg+i
This is going to take the value of the first element of the array and add i to it. Instead you want to do:
*(porg+i)
That will add to the pointer and then dereference it to get the value.
To clarify more fully with the comparison because this is a very important concept for pointers. porg is defined as a char*. This means that you have a variable that has the memory address of a 'char'. When you use the dereference operator (*, for example *porg) on the variable, it returns the value at stored in that piece of memory. However, you can add a number to the memory location to move to a different memory location. porg + 1 is going to return the memory location after porg. Therefore, when you do *porg + 1 you are getting the value at the memory address and adding 1 to it. On the other hand, when you do *(porg + 1) you are getting the value at the memory address one after where porg is pointing to. This is useful for arrays because arrays are store their values one after another. However, a more understandable notation for doing this is: porg[1]. This says "get the value 1 after the beginning of the array" or in other words "get the second element of the array".
All conditions in C are checking if the value is zero or non-zero. Zero means false, and every other value means true. When you use this expression (*porg + 1) for a condition it is going to do the calculation (value at porg + 1) and check if it is zero or not.
This leads me to the other very important concept for programming in C. An int can only hold values up to a certain size. If the variable is added to enough where it is larger than that maximum value, it will cycle around to 0. So lets say the maximum value of an int is 256 (it is in fact much larger). If you have an int that has the value of 256 and add 1 to it, it will become zero instead of 257. In reality the maximum number is 65,536 for most compilers so this is why it is taking so long. It is waiting until *porg + i is greater than 65,536 so that it becomes zero again.
Try including string.h:
#include <string.h>
Then use the built-in strcmp() function. The existing string functions have already been written to be as fast as possible in most situations.
Also, I think your for statement is messed up:
for(i=0;*porg+i;i++)
That's going to dereference the pointer, then add i to it. I'm surprised the for loop ever exits.
If you change it to this, it should work:
for(i=0;porg[i];i++)
Your original string is also one longer than you think it is. You allocate 10 bytes, but it's actually 11 bytes long. A string (in quotes) is always ended with a null character. You need to declare 11 bytes for your char array.
Another issue:
if(!(*porg+i==*pcmp+i))
should be changed to
if(!(porg[i]==pcmp[i]))
For the same reasons listed above.
What's the purpose of array indices starting at 0 in most programming languages, in contrast to the ordinal way in which we refer to most things IRL (first, second, third, etc.)? What's the logic or utility behind that?
I'm completely used to it by now, but never stopped to think about the reason behind it.
Update: One benefit I read about from Googling is that for loops can have i < n if you want to go up to n.
Dijkstra lays out the reasoning in Why numbering should start at zero.
When dealing with a sequence of length N, the elements of which we wish to distinguish by subscript, the next vexing question is what subscript value to assign to its starting element...
when starting with subscript 1, the subscript range 1 ≤ i < N+1; starting with 0, however, gives the nicer range 0 ≤ i < N. So let us let our ordinals start at zero: an element's ordinal (subscript) equals the number of elements preceding it in the sequence. And the moral of the story is that we had better regard —after all those centuries!— zero as a most natural number.
When we're accessing item by index like a[i] the compiler converts it to [a+i]. So the index of first element is zero because [a+0] will give us 'a' that points to the first item in array. This is quite obviously for, say, C++ but not for more recent languages such as C#.
Dijkstra wrote a really interesting paper about this, in 1982: Why numbering should start at zero.
You may google for it, there's been a lot of discussions about it. I'd say that the fact that the offset of the first element from the beginning (which it is) is zero certainly makes sense.
Because Dijkstra said so.
In my old assembler days it was natural for the offset to start at zero.
dcl foo(9)
ldx0 0 'offset to index register 0
lda foo,x0 'get first element
adx0 1,du 'get 2nd
ldq foo,x0
When looking at it from the perspective of the hardware it makes more sense.