I want to set all the index value to -1 in a double array.
Here is my code :
double dp[505];
memset(dp,-1,sizeof(dp));
cout<<dp[0]<<"\n";
But it is showing nan when i try to print its value.
What does nan mean?
Is it possible to use memset() in double array?
In C++, you can write:
double initValue = -1;
std::fill_n(dp, 505, initValue);
memsetting a double array with a non-double value won't work.
memset operates on bytes, not floats, and a double with all bytes set to -1 does not equal -1. I think you're looking for std::fill:
#include <algorithm>
std::fill(dp, dp + 505, -1.0);
Or, in C++11:
#include <algorithm>
#include <iterator>
std::fill(std::begin(dp), std::end(dp), -1.0);
You have set each element of the array to be filled with the byte 0xFF (i.e. the char representation of -1).
No floating point number is represented by a series of 0xFF bytes, so on printing the double, you see NaN (i.e. 'not a number'). This is in apparent contrast to memset'ting the bytes to zero, which is legal as a string of 0 bytes is a double with value zero. See Is it legal to use memset(,0,) on array of doubles?.
If you meant to set every entry to -1.0 (i.e. a double), then use std::fill or std::fill_n in C++ or a loop in C, e.g.
int n;
for (n = 0 ; n < 505 ; n++)
dp[n] = -1.0;
From the man page of memset:
The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.
The problem is that you want to fill an array of doubles with the constant -1.0 but sizeof(double) > 1 so memset actually fills in garbage which happens to end up as a NaN.
If you are using C++, the std::fill function is your friend. Actually, since you are writing to your array for the first time, std::uninitialized_fill would be correct. Although for the builtin double type there should be no difference but it is always good to be precise.
constexpr std::size_t length = 505;
double values[length];
std::uninitialized_fill(values, values + length, -1.0);
memset sets bytes, so you get double-values where each byte is -1.
Instead in C++ use std::vector, then write
vector<double> dp( 505, -1.0 );
It's that simple.
If dp is a global vector and you need to set it to -1 a number of times, then you can simply do this:
dp = vector<double>( dp.size(), -1.0 );
However, it's generally not a good idea to use non-const global variables.
Alternatively one can use std::fill, or just a loop, or just about any technique that still treat the double values as double values. But std::vector is preferable also for many other reasons than greatly simplifying the fill-it task. In particular a std::vector can be resized, it takes care of copying, and it automates the memory management, doing that part correctly and transparent to you.
nan means not a number.
cant see why its not working.
maybe because precision is not set : (cout.precision(15);)
check this:
How do I print a double value with full precision using cout?
But im not sure at all it will works :o
i checked memset source code and there's no problem with negative :D
But it can be a problem with doubles :
memset(dst0, c0, length) void *dst0;
register int c0;
register size_t length;
Have you tried to compile with Werror flag ?
Although answers for you question have been given, I just wanted you to note that
sizeof(dp)
outputs the number of bytes used to code the variable in memory.
In your case, dp is a pointer to a double. It will then be equal to the size of a pointer (4), no matter wether or not memery has been allocated.
sizeof(*dp) will output the size of a double (8).
In order to use the length of a
Related
I have initialised the entire array with value 1 but the output is showing some garbage value. But this program works correctly if i use 0 or -1 in place of 1. So are there some restrictions on what type of values can be initialised using memset.
int main(){
int a[100];
memset(a,1,sizeof(a));
cout<<a[5]<<endl;
return 0;
}
memset, as the other say, sets every byte of the array at the specified value.
The reason this works with 0 and -1 is because both use the same repeating pattern on arbitrary sizes:
(int) -1 is 0xffffffff
(char) -1 is 0xff
so filling a memory region with 0xff will effectively fill the array with -1.
However, if you're filling it with 1, you are setting every byte to 0x01; hence, it would be the same as setting every integer to the value 0x01010101, which is very unlikely what you want.
Memset fills bytes, from cppreference:
Converts the value ch to unsigned char and copies it into each of the first count characters of the object pointed to by dest.
Your int takes several bytes, e.g. a 32bit int will be filled with 1,1,1,1 (in base 256, endianess doesn't matter in this case), which you then falsly interpreted as a "garbage" value.
The other answers have explained std::memset already. But it's best to avoid such low level features and program at a higher level. So just use the Standard Library and its C++11 std::array
#include <array>
std::array<int, 100> a;
a.fill(1);
Or if you prefer C-style arrays, still use the Standard Library with the std::fill algorithm as indicated by #BoPersson
#include <algorithm>
#include <iterator>
int a[100];
std::fill(std::begin(a), std::end(a), 1);
In most implementations, both versions will call std::memset if it is safe to do so.
memset is an operation that sets bits.
If you want to set a value use a for-loop.
Consider a 4-bit-integer:
Its value is 1 when the bits are 0001 but memset sets it to 1111
I just came across an extremely strange problem. The function I have is simply:
int strStr(string haystack, string needle) {
for(int i=0; i<=(haystack.length()-needle.length()); i++){
cout<<"i "<<i<<endl;
}
return 0;
}
Then if I call strStr("", "a"), although haystack.length()-needle.length()=-1, this will not return 0, you can try it yourself...
This is because .length() (and .size()) return size_t, which is an unsigned int. You think you get a negative number, when in fact it underflows back to the maximum value for size_t (On my machine, this is 18446744073709551615). This means your for loop will loop through all the possible values of size_t, instead of just exiting immediately like you expect.
To get the result you want, you can explicitly convert the sizes to ints, rather than unsigned ints (See aslgs answer), although this may fail for strings with sufficient length (Enough to over/under flow a standard int)
Edit:
Two solutions from the comments below:
(Nir Friedman) Instead of using int as in aslg's answer, include the header and use an int64_t, which will avoid the problem mentioned above.
(rici) Turn your for loop into for(int i = 0;needle.length() + i <= haystack.length();i ++){, which avoid the problem all together by rearranging the equation to avoid the subtraction all together.
(haystack.length()-needle.length())
length returns a size_t, in other words an unsigned int. Given the size of your strings, 0 and 1 respectively, when you calculate the difference it underflows and becomes the maximum possible value for an unsigned int. (Which is approximately 4.2 billions for a storage of 4 bytes, but could be a different value)
i<=(haystack.length()-needle.length())
The indexer i is converted by the compiler into an unsigned int to match the type. So you're gonna have to wait until i is greater than the max possible value for an unsigned int. It's not going to stop.
Solution:
You have to convert the result of each method to int, like so,
i <= ( (int)haystack.length() - (int)needle.length() )
I'm writing a method that creates a copy of an array of arrays of floats. I was getting some extremely weird values after debugging this, so I thought I'd ask about this since I wasn't able to figure this out by reading about C++ array FAQs.
Here's the relevant parts of the code (it's part of an enormous program, with most of the stuff irrelevant for this post):
// height and width are integer global variables
void method () {
float testArray[height][width];
for(int j = 0; j < height; ++j) {
for(int i = 0; i < width; ++i) {
testArray[j][i] -= 0.0;
std::cout << testArray[j][i] << std::endl;
}
}
}
(In my tests, height = 32 and width = 256, but that shouldn't be relevant.) When I initialize testArray, it's values should all be 0.0, correct? Then, in the loop, I subtract 0.0 from a certain element in testArray, which should logically not change the value at all. But printing the values of testArray as a debugging step result in some weird values, such as the following snippet:
[...]
0
[...]
-3.23805e-24
[...]
8.40779e-45
[...]
1.79513e+37
[...]
0
[...]
3.19586e+36
[...]
The most worrisome values are the infinite ones, such as the fourth number listed above. I honestly don't know why this is occurring. Shouldn't all these values still be approximately 0.0? I thought it had to do with imprecision of floating point arithmetic, but that shouldn't result in an infinite value ....
No, when you declare your array like that it will be uninitialized since it's a builtin type. You'll need to initialize it to zero yourself before doing the subtraction.
But note that declaring an array as you have (with presumably non-const dimensions) is a compiler extension and not part of the language.
I would just use vector which solves both problems at once.
std::vector<std::vector<float> > testArray(height, std::vector<float>(width));
Try initializing the values in the array:
float testArray[height][width] = {};
This line creates an uninitialized array, element values can be any garbage:
float testArray[height][width];
To initialize it with float default values (zero) use following syntax:
float testArray[height][width] = {};
THIS ANSWER IS WRONG, BUT I AM LEAVING IT SO NOONE TRIES IT!
Use this very explicit definition:
float testArray[height][width] = {{0.0f}};
to ensure that every value in your array is initialized to zero. Otherwise, the values in the array will be undefined. I feel that this is the most "readable" solution.
WHY IS IT WRONG?
As #Dave mentions below, although this solution works for this case, it is misleading. It explicitly assignes only the first element of testArray to 0.0, while it value-initializes all the other elements in the array.
The correct solution is indeed:
float testArray[height][width] = {};
which value-initializes all the elements in the array (to the default value 0.0f for type float.
I have allocated a big double vector, lets say with 100000 element. At some point in my code, I want to set all elements to a constant, nonzero value. How can I do this without using a for loop over all elements?
I am also using the blas package, if it helps.
You could use std::fill (#include <algorithm>):
std::fill(v.begin(), v.end(), 1);
This is essentially also only a loop of course..
'fill' is right from what you've said.
Be aware that it's also possible to construct a vector full of a specified value:
std::vector<double> vec(100000, 3.14);
So if "at some point" means "immediately after construction", do this instead. Also, it means you can do this:
std::vector<double>(100000, 3.14).swap(vec);
which might be useful if "at some point" means "immediately after changing the size", and you expect/want the vector to be reallocated ("expect" if you're making it bigger than its prior capacity, "want" if you're making it much smaller and want it trimmed to save memory).
You always use memset() if you don't want to loop.
That is, memset(myarr, 5, arrsize); in order to fill it with all 5's. Beware of implicit conversion to unsigned char.
SYNOPSIS
#include <string.h>
void *
memset(void *b, int c, size_t len);
DESCRIPTION
The memset() function writes len bytes of value c (converted to an
unsigned char) to the byte string b.
And if the vector is large, and you need it to go fast and you are using gcc, then :
Code generation of block move (memcpy)
and block set (memset) was rewritten.
GCC can now pick the best algorithm
(loop, unrolled loop, instruction with
rep prefix or a library call) based on
the size of the block being copied and
the CPU being optimized for.
How do I automatically set a dynamically allocated array of floats to zero(0.0) during allocation
Is this OK
float* delay_line = new float[filter_len];
//THIS
memset(delay_line, 0.0, filter_len); //can I do this for a float??
//OR THIS
for (int i = 0; i < filter_len; i++)
delay_line[i] = 0.0;
Which is the most efficient way
Thanks
Use sizeof(float) * filter_len unless you are working in some odd implementation where sizeof(float) == sizeof(char).
memset(delay_line, 0, sizeof(float) * filter_len);
Edit: As Stephan202 points out in the comments, 0.0 is a particularly easy floating point value to code for memset since the IEEE standard representation for 0.0 is all zero bits.
memset is operating in the realm of memory, not the realm of numbers. The second parameter, declared an int, is cast to an unsigned char. If your implementation of C++ uses four bytes per float, the following relationships hold:
If you memset the float with 0, the value will be 0.0.
If you memset the float with 1, the value will be 2.36943e-38.
If you memset the float with 42, the value will be 1.51137e-13.
If you memset the float with 64, the value will be 3.00392.
So zero is a special case.
If this seems peculiar, recall that memset is declared in <cstring> or <string.h>, and is often used for making things like "***************" or "------------------". That it can also be used to zero memory is a nifty side-effect.
As Milan Babuškov points out in the comments, there is a function bzero (nonstandard and deprecated), available for the moment on Mac and Linux but not Microsoft, which, because it is specially tailored to setting memory to zero, safely omits a few instructions. If you use it, and a puritanical future release of your compiler omits it, it is trivial to implement bzero yourself in a local compatibility patch, unless the future release has re-used the name for some other purpose.
use
#include <algorithm>
...
std::fill_n( delay_line, filer_len, 0 )
The elements of a dynamically allocated array can be initialized to the default value of the element type by following the array size by an empty pair of parentheses:
float* delay_line = new float[filter_len]();
Use a std::vector instead:
std::vector<float> delay_line( filter_len );
The vector will be zero initialised.
Now that we're at it: even better would be to use the vector class.
std::vector< float > delay_line( filter_len, 0.0 );
Another option is to use calloc to allocate and zero at the same time:
float *delay_line = (float *)calloc(sizeof(float), filter_len);
The advantage here is that, depending on your malloc implementation, it may be possible to avoid zeroing the array if it's known to be allocated from memory that's already zeroed (as pages allocated from the operating system often are)
Keep in mind that you must use free() rather than delete [] on such an array.
Which is the most efficient way
memset maybe a tad faster, BUT WHO CARES!?!? Micro-optimization down to this level is a total waste of time, unless you're programming a calculator, and probably not even then.
I think the memset way is clearer, BUT I think you really had better check your man-pages for memset... I'd be suprised if your version of standard libraries has a memset function which takes a float as the second argument.
PS: The bit pattern representing zero is the same for both integers and floats... this is by design, not just good luck.
Good Luck ;-)
Cheers. Keith.