#include <stdio.h>
#include <string.h>
int main (int argc, const char * argv[])
{
char strInts[] = "10 223 21 67";
char delim[] = " ";
char *token;
int i;
token = strtok(strInts, delim);
while( token != NULL )
{
sscanf(token, "%d", &i);
printf("%d\n",i);
token = strtok( NULL, delim );
}
return 0;
}
Monday, March 8, 2010
Parse the text with integer values
Saturday, February 13, 2010
Integer is power of 2
inline bool isPowerOf2(int i)Source: http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.12
{
return i > 0 && (i & (i - 1)) == 0;
}
#include <iostream>
using namespace std;
inline bool isPowerOf2(int i)
{
return i > 0 && (i & (i - 1)) == 0;
}
int main()
{
cout << "64 is " << (isPowerOf2(64) ? "" : " not ") << "power of 2" << endl;
cout << "100 is " << (isPowerOf2(100) ? "" : " not ") << "power of 2" << endl;
cout << "128 is " << (isPowerOf2(128) ? "" : " not ") << "power of 2" << endl;
cout << "1024 is " << (isPowerOf2(1024) ? "" : " not ") << "power of 2" << endl;
return 0;
}
Sunday, December 27, 2009
Software Rendering School
On DevMaster.net I found a series of tutorials: Software Rendering School.
I’ve read first two parts – it is really amazing, everything is explained is a very simple language and does not require to remember the University mathematics.
Few nice things from the beginning:
- You may find an explanation what is the difference between the points and vertices – the points are simply random positions set by their coordinates, and vertices may have more data bound to them, vertices are positions bound to primitives like triangle.
- The basic operations you can perform with the points are translation, scaling and rotation.
- Translation is a simple movement:
new.x = point.x + translate.x;
new.y = point.y + translate.y;
new.z = point.z + translate.z
- The scaling is also a kind of a movement, but we multiply the coordinates:
new.x = point.x * scale.x;
new.y = point.y * scale.y;
new.z = point.z * scale.z;
- The most complex operation is the rotation:
//X-Rotation
new.x = v.x
new.y = v.y * cos(a) – v.z * sin(a)
new.z = v.y * sin(a) + v.z * cos(a)
//Y-Rotation
new.x = v.x * cos(a) – v.z * sin(a)
new.y = v.y
new.z = v.x * sin(a) + v.z * cos(a)
//Z-Rotation
new.x = v.x * cos(a) – v.y * sin(a)
new.y = v.y * sin(a) + v.x * cos(a)
new.z = v.z
- Vector, in the simplest way, can be described by its position, direction and magnitude.
- Dot product is cos of the angle between two vectors:
dot = v1.x * v2.x + v1.y + v2.y + v1.z * v2.z
dot = cos(a)
More about Dot Product: http://mathworld.wolfram.com/DotProduct.html
- Cross product of two vectors is another vector, which is perpendicular to both source vectors:
new.x = v1.y * v2.z – v2.z – v1.z
new.y = v2.x * v1.z – v1.x * v2.z
new.z = v1.x * v2.y – v2.x * v2.y
More about Cross Product: http://mathworld.wolfram.com/CrossProduct.html
And here is a joke about the subject:
Question: What do you get if you will cross an elephant and a grape?
Answer: elephant grape sine-of-theta
- Matrix is an object with a given number of rows and columns.
- Parallel projection:
x2 = x1 + viewportWidth / 2
y2 = –y1 + viewportHeight / 2
z2 = 0
- Perspective projection is clear when you know that
y2 / y1 = z2 / z1 = d / z
or
x2 / x1 = z2 / z1 = d / z
where d is the distance to the projection plane.
Wednesday, November 25, 2009
! a || b
if a is true, so NOT a is false and so when b is true, the entire expression is true.
if a is false, so NOT a is true, and b can be either true of false.
Tuesday, November 10, 2009
String to double
C: strtod in stdlib.h
C++: strtod in cstdlib
I knew about atof.
But this function does not work with the strings like "20nn". So, for example, how to check if this conatins a valid double?
I made even a function and tested it in this code:
#include <cstdio>And then I see (thanks to EE), that there are a set of functions such as strtod, strtof, etc. Actually, I knew about strtol, so I could guess that should be also strtod. But I didn't. :)
#include <string>
bool is_valid_double(const char* str)
{
while (str && *str && *str == ' ')
str++;
if (*str && *str == '-')
str++;
while (str && *str)
{
if (!isdigit(*str) && (*str != '.'))
{
if (*str == ' ')
{
while (str && *str && *str == ' ')
str++;
if (!*str)
return true;
}
return false;
}
str++;
}
return true;
}
int main()
{
char sz[16] = { 0 };
sprintf(sz, "%f", 20.0);
bool b = is_valid_double(sz);
strcpy(sz, " 20.00");
b = is_valid_double(sz);
strcpy(sz, " 20.00 ");
b = is_valid_double(sz);
strcpy(sz, " -20.00 ");
b = is_valid_double(sz);
strcpy(sz, " --20.00");
b = is_valid_double(sz);
strcpy(sz, " 20.00 2");
b = is_valid_double(sz);
strcpy(sz, " 20nn ");
b = is_valid_double(sz);
return 0;
}
Sunday, November 1, 2009
Aliasing
1. Krister Walfridsson. Aliasing, pointer casts and gcc 3.3.
2. Mike Acton. Understanding Strict Aliasing.
The main idea is simple:
Pointer casts are evil (both explicit and implicit casts), and you should think twice before adding a pointer cast to the code...Scott Meyers says about it softer:
If you’re coming to C++ from C, Java, or C#, take note, because casting in those languages is more necessary and less dangerous than in C++. But C++ is not C. It’s not Java. It’s not C#. In this language, casting is a feature you want to approach with great respect.Key points:
1. One pointer is said to alias another pointer when both refer to the same location or object.
2. Pointers of different types cannot point to the same address.
3. Code below:
intCompiler may optimize as:
foo(float *f) {
int i = 23;
*f = 5.0;
/* A float* cannot point on the same address as int*. */
return i * 2;
}
int4. Many architectures requires that pointers are correctly aligned when
foo(float *f) {
*f = 5.0;
return 46;
}
accessing objects bigger than a byte. So the following code may not work:
char* data;The reason is that the behavior is undefined when you assign an unaligned value to a pointer that points to a type that need to be aligned. What happens in the example above is that compiler notices that tmp and header must be aligned, so it may use an inlined memcpy that uses instructions that assumes aligned data.
struct foo_header *tmp, header;
tmp = data + offset;
memcpy(&header, tmp, sizeof(header));
Here is fix:
char* data;
struct foo_header header;
memcpy(&header, data + offset, sizeof(header));
Wednesday, August 5, 2009
Чтобы не забывать
#include <iostream>
using namespace std;
bool is_even_number(int n)
{
return ((n + 1) & 1);
}
bool is_odd_number(int n)
{
return (n & 1);
}
int nearest_smaller_2(int n)
{
return (n & ~1);
}
int nearest_2(int n)
{
return ((n + 1) & ~1);
}
int nearest_4(int n)
{
return ((n + 3) & ~3);
}
int nearest_8(int n)
{
return (((n - 1) / 7) << 3) + 8;
}
int main()
{
for (int i = 0; i < 33; i++)
{
cout << i << " " << is_even_number(i) << " " << is_odd_number(i);
cout << " " << nearest_smaller_2(i);
cout << " " << nearest_2(i);
cout << " " << nearest_4(i) << " " << nearest_8(i) << endl;
}
return 0;
}unsigned int ui16To32(unsigned short a, unsigned short b)А бывает нужно, особенно, если расчитывается сколько выделять памяти
{
return ((a << 16) | b);
}
unsigned short ui6To16(unsigned char a, unsigned char b)
{
return ((a << 8) | b);
}
Интересные алгоритмы с использованием битовых операций можно найти здесь:
http://www.coranac.com/documents/bittrick/
Математика для чисел с фиксированной точкой здесь:
http://www.coranac.com/tonc/text/fixed.htm
Системы исчисления и битовые операции здесь:
http://www.coranac.com/tonc/text/numbers.htm