Pages

Showing posts with label C++. Show all posts
Showing posts with label C++. Show all posts

Monday, March 8, 2010

Parse the text with integer values

Simply a kind of an interesting task: retrieve all integer values from a string like "10 223 21 67"
#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;
}

Saturday, February 13, 2010

Integer is power of 2

That's simple:
inline bool isPowerOf2(int i)
{
return i > 0 && (i & (i - 1)) == 0;
}
Source: http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.12
#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

    This boolean expression  ( NOT a OR b) has a very specific meaning in English: “if a is true, then b must be true”.
    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

    Probably, the C++ standard library is unlimited. There are so many functions I've never heard about. For example, only today I found out that there is strtod function:

    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>
    #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;
    }
    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. :)

    Sunday, November 1, 2009

    Aliasing

    Here are two articles about the subject:
    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:
    int
    foo(float *f) {
    int i = 23;
    *f = 5.0;
    /* A float* cannot point on the same address as int*. */
    return i * 2;
    }
    Compiler may optimize as:
    int
    foo(float *f) {
    *f = 5.0;
    return 46;
    }
    4. Many architectures requires that pointers are correctly aligned when
    accessing objects bigger than a byte. So the following code may not work:
    char* data;
    struct foo_header *tmp, header;

    tmp = data + offset;
    memcpy(&header, tmp, sizeof(header));
    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.
    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