Absolute value of a float

I did a job interview a while ago where I was asked, as the first question of a phone interview, how I would calculate the absolute value of a float. I didn’t answer this very well at all, in part due to the fact I wasn’t aware the interview I was going into was going to be a technical one, but more due to the fact that I didn’t have the greatest understanding about how a float actually works. I knew vaguely that it stored the mantissa and exponent, but had no idea about how many bits each took up or where those bits were located. And I just assumed that all negative numbers would be handled in two’s complement, similar to integers.

I did so horrendously bad at that interview in general that I went out and bought a book called Write Great Code: Volume 1: Understanding the MachineI’m only up to chapter 4 so far, but wow, this book is great. I feel like it should be required reading for all computer science undergrads, and wish I’d been taught a lot of this stuff much earlier.

So chapter 4 deals with floating point representation, and the question of finding the absolute value of a float that has been haunting me since the interview now seems a lot easier to tackle.

I’ve learned that single precision IEEE floating point format does indeed store a mantissa and exponent, but the mantissa uses 23 bits, followed by the exponent with 8 bits, and the remaining bit simply handling the sign:

2000px-ieee_754_single_floating_point_format-svg

So, finding the absolute value of this now seems super easy, we just need to zero that sign bit:

float myFloat = -1.45;
float absFloat = myFloat & 0x7FFFFFFF;

Ok, so that actually doesn’t work. Binary operators don’t actually work on floating point variables in C++. I guess that makes sense, really, the interview question would have been way too easy otherwise.

Casting to an int isn’t going to work, because that just rearranges how the value is stored (no mantissa or exponent there) not to mention losing any information following the decimal point.

After a quick Google I saw someone mention using a union. That sounds like a nice solution, let’s try that.

union hackCasting{
    int myInt;
    float myFloat;
};

hackCasting myUnion;
myUnion.myFloat = -1.45;
float absFloat = myUnion.myInt & 0x7FFFFFFF;
std::cout << absFloat << std::endl;

Which gave me the output of 1.06913e+09. Hmm. Clearly something is going wrong there. Oh, an inherent cast by creating a new float (absFloat) and storing my int calculation there.

union hackCasting{
    uint32_t myInt;
    float myFloat;
};

hackCasting myUnion;
myUnion.myFloat = -1.45;
myUnion.myInt = myUnion.myInt & 0x7FFFFFFF;
std::cout << myUnion.myFloat << std::endl;

Hurrah, a correct result of 1.45. (And a change to using an unsigned int after finding a comment by Tim Schaeffer on StackOverflow. Not sure if it’s actually Mr Schaeffer, but helpful all the same!)

So, question complete – take that interview question.

Advertisements

Enemy interactions

Sooo long without an update. My excuses include: laziness, being so close to releasing a game in my day job leaves no mental energy for home projects, travel, and working with a mentor outside of work hours to better understand data oriented development.

I have slowly been refactoring the Enemy class. Not long into my first attempt I saw how similar the PlayerObject and EnemyObject were going to be, so I created a ShipObject to stop myself from repeating code. I moved the component updating and shoot code into the ShipObject which leaves the Player update all about input handling:

GLFWwindow* currentContext = glfwGetCurrentContext();
PhysicsComponent* physicsComponent = dynamic_cast<PhysicsComponent*>(GameObject::GetComponent(PHYSICS));
if (physicsComponent != nullptr) {
    if (glfwGetKey(currentContext, 'W')) {
        physicsComponent->AddForce(glm::vec2(150, 150));
    }

    if (glfwGetKey(currentContext, 'A')) {
        physicsComponent->AddRotation(3);
    }

    if (glfwGetKey(currentContext, 'D')) {
        physicsComponent->AddRotation(-3);
    }
    if (glfwGetKey(currentContext, GLFW_KEY_SPACE)) {
        shoot();
    }
}

ShipObject::Update(a_dDeltaTime);

So now for the Enemy. With all the rest of the clutter gone all I have left is the “AI” of the enemy following the player and shooting when within range. So the problem here is that the Enemy needs to know the position of the Player. In the old code I just passed the player’s vec3 position into the Enemy’s update function as a constant. However with my new GameObject approach I couldn’t really justify modifying my EnemyObject to use different Update parameters.

I briefly toyed with the idea of making the Enemy listen for changes to the Player’s position with some sort of Observer pattern. Despite wanting to practice that pattern a little, it seemed like a huge amount of overkill. So for now I’ve created a GetPosition function in PlayerObject, and the EnemyObject now contains a pointer to the PlayerObject in order to use this function when necessary.

I still don’t really like this since the EnemyObject now has full read/write access to the PlayerObject’s position (hmm, why am I even passing back the actual position in GetPosition? Why don’t I make a copy to pass back? Still, even with this improvement the Enemy has access to all the PlayerObject’s public functions – like adding components).

With that decision out of the way all that was left was adding in the “AI”. It remains basically unchanged from the original code – just modified to work with the new component system:

PhysicsComponent* physicsComponent = dynamic_cast<PhysicsComponent*>(GameObject::GetComponent(PHYSICS));
glm::vec3 playerPos = m_player->GetPosition();

glm::vec3 toPlayer = playerPos - physicsComponent->m_position;

float aimAngle = atan2(toPlayer.y, toPlayer.x);

if (aimAngle*180.0 / 3.14159 > physicsComponent->m_fRotationAngle + 90)
    physicsComponent->AddRotation(3);
else if (aimAngle*180.0 / 3.14159 < physicsComponent->m_fRotationAngle + 90)
    physicsComponent->AddRotation(-3);

if (physicsComponent->m_fRotationAngle + 90 > 180)
    physicsComponent->AddRotation(-360);
else if (physicsComponent->m_fRotationAngle + 90 < -180)
    physicsComponent->AddRotation(360);

physicsComponent->AddForce(glm::vec2(50, 50));

if (glm::distance(playerPos, physicsComponent->m_position) < 200) {
    ShipObject::shoot();
}

ShipObject::Update(a_dDeltaTime);

One thing I’m contemplating is creating a component similar to Unity’s “transform” component. This can store the position, rotation + scale. And then each other component should have access to the transform. This way I can remove all the code that looks like this:

SpriteComponent* spriteComponent = dynamic_cast<SpriteComponent*>(GameObject::GetComponent(SPRITE));
PhysicsComponent* physicsComponent = dynamic_cast<PhysicsComponent*>(GameObject::GetComponent(PHYSICS));
if (spriteComponent != nullptr) {
    if (physicsComponent != nullptr) {
        //Is there a better way to get these components to work together? I feel it's likely           to happen a lot.
        spriteComponent->m_position = physicsComponent->m_position;
        spriteComponent->m_fRotationAngle = physicsComponent->m_fRotationAngle;
    }
}

So, next step (unless there’s anyone who thinks this is a bad idea) is to create a transformComponent. Then perhaps I can finally get to collisions!

Thanks for all the comments from last time – they definitely give me a lot to think about and I think I will implement some of the suggestions soon.

Once again, all my code is on github if you’d like to read it without the ugly WordPress formatting.