# c# Unity - Matrix output incorrect on vector rotation

I have a input Vector (1,1,0) when I run it through a Unity Matrix4x4 class with a rotation of 90 degrees around the Z axis the output is (-0.9999999,1,0) which is nearly correct but strange. But (2,0,0) with the same degrees and axis rotation I get (1.192093e-07,2,0). The Y vector coordinate is correct, but why on earth is X set to 1.192093e-07? I cant explain why this is happening. I thought it would be set to (0,2,0).

The code I am using

using UnityEngine;
using System.Collections;

public class test : MonoBehaviour
{
public Vector3 translation;
public Quaternion rotation;
//public Vector3 eulerAngles;
public Vector3 input;
public Vector3 output;
public Matrix4x4 m;
// Use this for initialization
void Start ()
{
//transform.rotation = Quaternion.Euler(60F, 0, 45F);
}

// Update is called once per frame
void Update ()
{

input = new Vector3 (2, 0, 0);
rotation = Quaternion.AngleAxis(90, Vector3.forward);
m = Matrix4x4.TRS (Vector3.zero, rotation, Vector3.one);
output = m.MultiplyPoint3x4(input);

}
}


You can see Vector forward is the Z axis. I have scale as (1,1,1) and no transformation set. I have Unity set to 2D view. I have a main camera with a Orthographic view, clipping plane near is 0 and far is 1000 and its depth is -1, its vector is (0,0,0).

When I use (2,0,0) as the input this is the result of the matrix

[E00] = 5.960464e-08 [E01] = -0.9999999 [E02] = 0 [E03] = 0 [E10] = 0.9999999 [E11] = 5.960464e-08 [E12] = 0 [E13] = 0 [E20] = 0 [E21] = 0 [E22] = 1 [E23] = 0 [E30] = 0 [E31] = 0[E32] = 0 [E33] = 1

• ah rounding errors, the bane of every programmer working with floating points Oct 23 '14 at 22:17
• @ratchetfreak I wouldn't be so bothered if it was 0.1 but 1.192093e-07? Oct 23 '14 at 22:20
• that's even less than 0.1; it's 0.0000001192093 the e signals scientific notation and the numbers after it is the exponent Oct 23 '14 at 22:22
• docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
– user1430
Oct 23 '14 at 22:23
• Is the e- mean exponant 7 zeros before the number. I thought it meant 1.1920930000000 Oct 23 '14 at 22:45

## 2 Answers

Floating point math is not perfect. You're trying to compress an infinite set (all real numbers) into an extremely finite space (32 bits).

Consequently, not every number can be accurately represented, and some numbers will suffer from rounding error. Basically, as you do increasingly more math on some particular value, you increase the chance(*) that the resulting calculation will drift in some form. This is why, for example, you don't want to represent successive rotations of objects by doing something like:

transform = transform * rotation;


Even if you have pure rotations in there, over many successive frames you may introduce enough error in the computation results that you start to observe distortion in the final model due to the fact that your error is introducing, effectively, scaling or shearing terms.

The math you're doing involves several multiplies, adds, and transcendental functions (sine and cosine). It's not unreasonable that certain inputs will result in errors carried through those computations that result in a technically-mathematically-incorrect answer.

The values you are reporting seem sufficiently close as to be considered normal, in practice, however. If this is not actually causing observable problems in your game, I wouldn't worry about it.

(*) I say "chance" lightly; for a fixed set of inputs, a computation will be deterministic on a particular machine, but when you don't know the potential inputs it becomes much harder to determine if you'll get rounding error and such, so the amount of practical observed error can appear "random."

• Thank you. I thought the exponant was right of the number. I was wrong. Thats why i thought 1.1 was way off 0. Oct 23 '14 at 22:49

When you create a rotation matrix or quaternion from an angle, you are actually taking the sine and cosine of a numeric value in radians. Your value in degrees is being converted to radians, so 90 degrees becomes π/4.

π is not something that can be represented accurately in floating point. This is where the accuracy loss is coming from.

If you take the sine or cosine of that slightly inaccurate angle, the result is slightly inaccurate, and any transformations you do with it will also be slightly inaccurate.

As Josh Petrie says - this inaccuracy usually does not matter, so long as you avoid accumulating the error.

If you need an exact rotation by 90 degrees, you can manually construct an exact transformation matrix for that specific case (because sin(90°) = 1 and cos(90°) = 0).